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_channels_defines.c25
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c3
-rw-r--r--source/blender/editors/animation/anim_deps.c10
-rw-r--r--source/blender/editors/animation/anim_draw.c26
-rw-r--r--source/blender/editors/animation/anim_filter.c13
-rw-r--r--source/blender/editors/animation/anim_markers.c14
-rw-r--r--source/blender/editors/animation/anim_ops.c10
-rw-r--r--source/blender/editors/animation/keyframes_draw.c29
-rw-r--r--source/blender/editors/animation/keyframes_general.c19
-rw-r--r--source/blender/editors/armature/armature_select.c4
-rw-r--r--source/blender/editors/armature/armature_utils.c2
-rw-r--r--source/blender/editors/armature/pose_edit.c23
-rw-r--r--source/blender/editors/curve/editcurve.c4
-rw-r--r--source/blender/editors/curve/editcurve_paint.c32
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt59
-rw-r--r--source/blender/editors/gizmo_library/CMakeLists.txt1
-rw-r--r--source/blender/editors/gizmo_library/gizmo_draw_utils.c34
-rw-r--r--source/blender/editors/gizmo_library/gizmo_library_intern.h10
-rw-r--r--source/blender/editors/gizmo_library/gizmo_library_presets.c36
-rw-r--r--source/blender/editors/gizmo_library/gizmo_library_utils.c36
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c84
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c154
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c89
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c128
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c290
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c206
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c160
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c146
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c68
-rw-r--r--source/blender/editors/gpencil/CMakeLists.txt7
-rw-r--r--source/blender/editors/gpencil/annotate_draw.c1066
-rw-r--r--source/blender/editors/gpencil/annotate_paint.c2393
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c1069
-rw-r--r--source/blender/editors/gpencil/editaction_gpencil.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_add_monkey.c1566
-rw-r--r--source/blender/editors/gpencil/gpencil_add_stroke.c248
-rw-r--r--source/blender/editors/gpencil/gpencil_brush.c711
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c87
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c1824
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c1596
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c1258
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h272
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c71
-rw-r--r--source/blender/editors/gpencil/gpencil_old.c219
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c543
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c1370
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c716
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c301
-rw-r--r--source/blender/editors/gpencil/gpencil_undo.c6
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c1264
-rw-r--r--source/blender/editors/include/ED_anim_api.h5
-rw-r--r--source/blender/editors/include/ED_datafiles.h63
-rw-r--r--source/blender/editors/include/ED_gizmo_library.h16
-rw-r--r--source/blender/editors/include/ED_gpencil.h189
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h7
-rw-r--r--source/blender/editors/include/ED_object.h36
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_transform.h14
-rw-r--r--source/blender/editors/include/ED_view3d.h4
-rw-r--r--source/blender/editors/include/UI_icons.h24
-rw-r--r--source/blender/editors/include/UI_interface.h18
-rw-r--r--source/blender/editors/include/UI_interface_icons.h2
-rw-r--r--source/blender/editors/interface/interface.c12
-rw-r--r--source/blender/editors/interface/interface_context_menu.c2
-rw-r--r--source/blender/editors/interface/interface_draw.c288
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c1
-rw-r--r--source/blender/editors/interface/interface_eyedropper_color.c93
-rw-r--r--source/blender/editors/interface/interface_icons.c131
-rw-r--r--source/blender/editors/interface/interface_icons_event.c6
-rw-r--r--source/blender/editors/interface/interface_intern.h11
-rw-r--r--source/blender/editors/interface/interface_layout.c8
-rw-r--r--source/blender/editors/interface/interface_ops.c3
-rw-r--r--source/blender/editors/interface/interface_panel.c42
-rw-r--r--source/blender/editors/interface/interface_query.c14
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c26
-rw-r--r--source/blender/editors/interface/interface_style.c29
-rw-r--r--source/blender/editors/interface/interface_templates.c359
-rw-r--r--source/blender/editors/interface/interface_utils.c4
-rw-r--r--source/blender/editors/interface/interface_widgets.c183
-rw-r--r--source/blender/editors/interface/resources.c22
-rw-r--r--source/blender/editors/interface/view2d.c26
-rw-r--r--source/blender/editors/interface/view2d_ops.c4
-rw-r--r--source/blender/editors/mask/mask_draw.c54
-rw-r--r--source/blender/editors/mesh/editmesh_add_gizmo.c100
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c154
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c110
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c68
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_spin.c118
-rw-r--r--source/blender/editors/mesh/editmesh_inset.c8
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c86
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c12
-rw-r--r--source/blender/editors/mesh/editmesh_select.c12
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c1360
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c2
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c23
-rw-r--r--source/blender/editors/mesh/mesh_intern.h10
-rw-r--r--source/blender/editors/mesh/mesh_ops.c30
-rw-r--r--source/blender/editors/object/CMakeLists.txt4
-rw-r--r--source/blender/editors/object/object_add.c152
-rw-r--r--source/blender/editors/object/object_bake_api.c24
-rw-r--r--source/blender/editors/object/object_data_transfer.c20
-rw-r--r--source/blender/editors/object/object_edit.c45
-rw-r--r--source/blender/editors/object/object_gpencil_modifier.c637
-rw-r--r--source/blender/editors/object/object_group.c11
-rw-r--r--source/blender/editors/object/object_intern.h15
-rw-r--r--source/blender/editors/object/object_modes.c18
-rw-r--r--source/blender/editors/object/object_modifier.c229
-rw-r--r--source/blender/editors/object/object_ops.c39
-rw-r--r--source/blender/editors/object/object_relations.c53
-rw-r--r--source/blender/editors/object/object_select.c5
-rw-r--r--source/blender/editors/object/object_shader_fx.c469
-rw-r--r--source/blender/editors/object/object_shapekey.c6
-rw-r--r--source/blender/editors/object/object_transform.c103
-rw-r--r--source/blender/editors/physics/particle_edit.c2
-rw-r--r--source/blender/editors/render/render_opengl.c98
-rw-r--r--source/blender/editors/render/render_preview.c221
-rw-r--r--source/blender/editors/render/render_shading.c8
-rw-r--r--source/blender/editors/render/render_update.c2
-rw-r--r--source/blender/editors/screen/area.c94
-rw-r--r--source/blender/editors/screen/glutil.c20
-rw-r--r--source/blender/editors/screen/screen_context.c86
-rw-r--r--source/blender/editors/screen/screen_draw.c38
-rw-r--r--source/blender/editors/screen/screen_intern.h2
-rw-r--r--source/blender/editors/screen/screen_ops.c19
-rw-r--r--source/blender/editors/screen/screendump.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c70
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c46
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c2
-rw-r--r--source/blender/editors/sound/sound_ops.c4
-rw-r--r--source/blender/editors/space_action/action_draw.c18
-rw-r--r--source/blender/editors/space_action/action_select.c69
-rw-r--r--source/blender/editors/space_api/spacetypes.c1
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c44
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c17
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c43
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c2
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c18
-rw-r--r--source/blender/editors/space_clip/clip_draw.c144
-rw-r--r--source/blender/editors/space_clip/clip_graph_draw.c20
-rw-r--r--source/blender/editors/space_clip/clip_utils.c4
-rw-r--r--source/blender/editors/space_clip/space_clip.c20
-rw-r--r--source/blender/editors/space_console/console_draw.c4
-rw-r--r--source/blender/editors/space_console/space_console.c19
-rw-r--r--source/blender/editors/space_file/file_draw.c14
-rw-r--r--source/blender/editors/space_file/file_panels.c33
-rw-r--r--source/blender/editors/space_file/space_file.c2
-rw-r--r--source/blender/editors/space_graph/graph_draw.c78
-rw-r--r--source/blender/editors/space_graph/space_graph.c6
-rw-r--r--source/blender/editors/space_image/image_buttons.c2
-rw-r--r--source/blender/editors/space_image/image_draw.c26
-rw-r--r--source/blender/editors/space_image/image_ops.c8
-rw-r--r--source/blender/editors/space_image/space_image.c22
-rw-r--r--source/blender/editors/space_info/info_stats.c36
-rw-r--r--source/blender/editors/space_info/textview.c12
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c3
-rw-r--r--source/blender/editors/space_nla/nla_channels.c1
-rw-r--r--source/blender/editors/space_nla/nla_draw.c38
-rw-r--r--source/blender/editors/space_node/drawnode.c206
-rw-r--r--source/blender/editors/space_node/node_draw.c40
-rw-r--r--source/blender/editors/space_node/node_edit.c90
-rw-r--r--source/blender/editors/space_node/node_gizmo.c202
-rw-r--r--source/blender/editors/space_node/node_intern.h12
-rw-r--r--source/blender/editors/space_node/node_ops.c3
-rw-r--r--source/blender/editors/space_node/space_node.c47
-rw-r--r--source/blender/editors/space_outliner/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c151
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.c954
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c904
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c541
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h60
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c388
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c30
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c179
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c190
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c50
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c5
-rw-r--r--source/blender/editors/space_sequencer/sequencer_preview.c2
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c6
-rw-r--r--source/blender/editors/space_text/space_text.c11
-rw-r--r--source/blender/editors/space_text/text_draw.c22
-rw-r--r--source/blender/editors/space_topbar/space_topbar.c4
-rw-r--r--source/blender/editors/space_view3d/drawobject.c113
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c145
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c66
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c22
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c28
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_armature.c66
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_camera.c180
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_empty.c80
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_forcefield.c54
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_lamp.c148
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate.c140
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c125
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_ruler.c212
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h28
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c49
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c33
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c68
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c6
-rw-r--r--source/blender/editors/transform/transform.c387
-rw-r--r--source/blender/editors/transform/transform.h6
-rw-r--r--source/blender/editors/transform/transform_constraints.c18
-rw-r--r--source/blender/editors/transform/transform_conversions.c332
-rw-r--r--source/blender/editors/transform/transform_generics.c36
-rw-r--r--source/blender/editors/transform/transform_gizmo_2d.c28
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c234
-rw-r--r--source/blender/editors/transform/transform_ops.c70
-rw-r--r--source/blender/editors/transform/transform_snap.c8
-rw-r--r--source/blender/editors/transform/transform_snap_object.c203
-rw-r--r--source/blender/editors/undo/ed_undo.c37
-rw-r--r--source/blender/editors/util/ed_util.c4
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c130
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c41
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c1010
226 files changed, 24634 insertions, 8983 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index c70790e0550..79b7c7988fd 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -64,6 +64,7 @@
#include "BKE_animsys.h"
#include "BKE_curve.h"
+#include "BKE_gpencil.h"
#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_nla.h"
@@ -146,7 +147,7 @@ static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale
short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
float color[3];
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
@@ -235,7 +236,7 @@ static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, f
short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
float color[3];
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
@@ -661,6 +662,8 @@ static int acf_object_icon(bAnimListElem *ale)
return ICON_OUTLINER_OB_SURFACE;
case OB_EMPTY:
return ICON_OUTLINER_OB_EMPTY;
+ case OB_GPENCIL:
+ return ICON_OUTLINER_OB_GREASEPENCIL;
default:
return ICON_OBJECT_DATA;
}
@@ -3868,7 +3871,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
/* for F-Curves, draw color-preview of curve behind checkbox */
if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
FCurve *fcu = (FCurve *)ale->data;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -3924,7 +3927,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
/* draw red underline if channel is disabled */
if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE) && (ale->flag & FCURVE_DISABLED)) {
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -3933,7 +3936,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
GPU_line_width(2.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, (float)offset, yminc);
immVertex2f(pos, (float)v2d->cur.xmax, yminc);
immEnd();
@@ -3952,7 +3955,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
short draw_sliders = 0;
float ymin_ofs = 0.0f;
float color[3];
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -4048,8 +4051,16 @@ static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void
return;
}
- if (ale_setting->type == ANIMTYPE_GPLAYER)
+ if (ale_setting->type == ANIMTYPE_GPLAYER) {
+ /* draw cache updates for settings that affect the visible strokes */
+ if (setting == ACHANNEL_SETTING_VISIBLE) {
+ bGPdata *gpd = (bGPdata *)ale_setting->id;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ }
+
+ /* UI updates */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
+ }
/* tag copy-on-write flushing (so that the settings will have an effect) */
if (ale_setting->id) {
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index d768be49ad4..3f22ac6fa3a 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -1727,8 +1727,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
bGPDlayer *gpl = (bGPDlayer *)ale->data;
/* try to delete the layer's data and the layer itself */
- BKE_gpencil_free_frames(gpl);
- BLI_freelinkN(&gpd->layers, gpl);
+ BKE_gpencil_layer_delete(gpd, gpl);
break;
}
case ANIMTYPE_MASKLAYER:
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index adb5a10c19d..898c8b6464a 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -435,6 +435,16 @@ void ANIM_animdata_update(bAnimContext *ac, ListBase *anim_data)
ANIM_list_elem_update(ac->bmain, ac->scene, ale);
}
}
+ else if (ale->update) {
+#if 0
+ if (G.debug & G_DEBUG) {
+ printf("%s: Unhandled animchannel updates (%d) for type=%d (%p)\n",
+ __func__, ale->update, ale->type, ale->data);
+ }
+#endif
+ /* Prevent crashes in cases where it can't be handled */
+ ale->update = 0;
+ }
BLI_assert(ale->update == 0);
}
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 51ba7d9c269..05ea3fd6314 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -87,8 +87,8 @@ void ANIM_draw_cfra_number(const bContext *C, View2D *v2d, short flag)
/* because the frame number text is subject to the same scaling as the contents of the view */
UI_view2d_scale_get(v2d, &xscale, NULL);
- gpuPushMatrix();
- gpuScale2f(1.0f / xscale, 1.0f);
+ GPU_matrix_push();
+ GPU_matrix_scale_2f(1.0f / xscale, 1.0f);
/* get timecode string
* - padding on str-buf passed so that it doesn't sit on the frame indicator
@@ -128,7 +128,7 @@ void ANIM_draw_cfra_number(const bContext *C, View2D *v2d, short flag)
numstr, col);
/* restore view transform */
- gpuPopMatrix();
+ GPU_matrix_pop();
}
/* General call for drawing current frame indicator in animation editor */
@@ -141,15 +141,15 @@ void ANIM_draw_cfra(const bContext *C, View2D *v2d, short flag)
GPU_line_width((flag & DRAWCFRA_WIDE) ? 3.0 : 2.0);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* Draw a light green line to indicate current frame */
immUniformThemeColor(TH_CFRAME);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, x, v2d->cur.ymin - 500.0f); /* XXX arbitrary... want it go to bottom */
immVertex2f(pos, x, v2d->cur.ymax);
immEnd();
@@ -170,8 +170,8 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
GPU_blend(true);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShadeAlpha(TH_ANIM_ACTIVE, -25, -30);
@@ -203,8 +203,8 @@ void ANIM_draw_framerange(Scene *scene, View2D *v2d)
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
GPU_blend(true);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShadeAlpha(TH_BACK, -25, -100);
@@ -222,7 +222,7 @@ void ANIM_draw_framerange(Scene *scene, View2D *v2d)
/* thin lines where the actual frames are */
immUniformThemeColorShade(TH_BACK, -60);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, (float)SFRA, v2d->cur.ymin);
immVertex2f(pos, (float)SFRA, v2d->cur.ymax);
@@ -552,11 +552,11 @@ static bool find_prev_next_keyframes(struct bContext *C, int *nextfra, int *prev
/* populate tree with keyframe nodes */
scene_to_keylist(&ads, scene, &keys, NULL);
- gpencil_to_keylist(&ads, scene->gpd, &keys);
+ gpencil_to_keylist(&ads, scene->gpd, &keys, false);
if (ob) {
ob_to_keylist(&ads, ob, &keys, NULL);
- gpencil_to_keylist(&ads, ob->gpd, &keys);
+ gpencil_to_keylist(&ads, ob->data, &keys, false);
}
if (mask) {
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index c59d24bbdf8..54590c5f66c 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -72,6 +72,7 @@
#include "DNA_speaker_types.h"
#include "DNA_world_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_brush_types.h"
#include "DNA_object_types.h"
#include "DNA_userdef_types.h"
#include "DNA_layer_types.h"
@@ -1660,7 +1661,7 @@ static size_t animdata_filter_gpencil_data(ListBase *anim_data, bDopeSheet *ads,
*/
if (filter_mode & ANIMFILTER_ANIMDATA) {
/* just add GPD as a channel - this will add everything needed */
- ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL);
+ ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, gpd);
}
else {
ListBase tmp_data = {NULL, NULL};
@@ -1711,7 +1712,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
/* Objects in the scene */
for (base = view_layer->object_bases.first; base; base = base->next) {
/* Only consider this object if it has got some GP data (saving on all the other tests) */
- if (base->object && base->object->gpd) {
+ if (base->object && (base->object->type == OB_GPENCIL)) {
Object *ob = base->object;
/* firstly, check if object can be included, by the following factors:
@@ -1748,7 +1749,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
/* finally, include this object's grease pencil datablock */
/* XXX: Should we store these under expanders per item? */
- items += animdata_filter_gpencil_data(anim_data, ads, ob->gpd, filter_mode);
+ items += animdata_filter_gpencil_data(anim_data, ads, ob->data, filter_mode);
}
}
}
@@ -2613,8 +2614,10 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data
}
/* grease pencil */
- if ((ob->gpd) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) {
- tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->gpd, filter_mode);
+ if ((ob->type == OB_GPENCIL) &&
+ (ob->data) && !(ads->filterflag & ADS_FILTER_NOGPENCIL))
+ {
+ tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->data, filter_mode);
}
}
END_ANIMFILTER_SUBCHANNELS;
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index c5f7782dcee..e1f4092c494 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -400,8 +400,8 @@ static void draw_marker(
if (flag & DRAW_MARKERS_LINES)
#endif
{
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -418,7 +418,7 @@ static void draw_marker(
immUniform1f("dash_width", 6.0f);
immUniform1f("dash_factor", 0.5f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, xpos + 0.5f, 12.0f);
immVertex2f(pos, xpos + 0.5f, (v2d->cur.ymax + 12.0f) * yscale);
immEnd();
@@ -486,7 +486,7 @@ void ED_markers_draw(const bContext *C, int flag)
v2d = UI_view2d_fromcontext(C);
if (flag & DRAW_MARKERS_MARGIN) {
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
const unsigned char shade[4] = {0, 0, 0, 16};
@@ -505,8 +505,8 @@ void ED_markers_draw(const bContext *C, int flag)
/* no time correction for framelen! space is drawn with old values */
ypixels = BLI_rcti_size_y(&v2d->mask);
UI_view2d_scale_get(v2d, &xscale, &yscale);
- gpuPushMatrix();
- gpuScale2f(1.0f / xscale, 1.0f);
+ GPU_matrix_push();
+ GPU_matrix_scale_2f(1.0f / xscale, 1.0f);
/* x-bounds with offset for text (adjust for long string, avoid checking string width) */
font_width_max = (10 * UI_DPI_FAC) / xscale;
@@ -529,7 +529,7 @@ void ED_markers_draw(const bContext *C, int flag)
}
}
- gpuPopMatrix();
+ GPU_matrix_pop();
}
/* ************************ Marker Wrappers API ********************* */
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 5f6b299c617..45fe7233f94 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -45,6 +45,7 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_sound.h"
+#include "BKE_scene.h"
#include "UI_view2d.h"
@@ -98,8 +99,13 @@ static void change_frame_apply(bContext *C, wmOperator *op)
float frame = RNA_float_get(op->ptr, "frame");
bool do_snap = RNA_boolean_get(op->ptr, "snap");
- if (do_snap && CTX_wm_space_seq(C)) {
- frame = BKE_sequencer_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false);
+ if (do_snap) {
+ if (CTX_wm_space_seq(C)) {
+ frame = BKE_sequencer_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false);
+ }
+ else {
+ frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame);
+ }
}
/* set the new frame number */
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 78ce24db503..a8b63e01ac1 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -48,6 +48,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_brush_types.h"
#include "DNA_mask_types.h"
#include "BKE_fcurve.h"
@@ -593,12 +594,12 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
}
if (block_len > 0) {
- Gwn_VertFormat *format = immVertexFormat();
- uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GWN_PRIM_TRIS, 6 * block_len);
+ immBegin(GPU_PRIM_TRIS, 6 * block_len);
for (ActKeyBlock *ab = blocks->first; ab; ab = ab->next) {
if (actkeyblock_is_valid(ab, keys)) {
if (ab->flag & ACTKEYBLOCK_FLAG_MOVING_HOLD) {
@@ -633,14 +634,14 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
if (key_len > 0) {
/* draw keys */
- Gwn_VertFormat *format = immVertexFormat();
- uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint size_id = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT);
- uint color_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
- uint outline_color_id = GWN_vertformat_attr_add(format, "outlineColor", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
GPU_enable_program_point_size();
- immBegin(GWN_PRIM_POINTS, key_len);
+ immBegin(GPU_PRIM_POINTS, key_len);
for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) {
if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax)) {
@@ -783,7 +784,7 @@ void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos
BLI_dlrbTree_init(&keys);
- gpencil_to_keylist(ads, gpd, &keys);
+ gpencil_to_keylist(ads, gpd, &keys, false);
BLI_dlrbTree_linkedlist_sync(&keys);
@@ -1019,7 +1020,7 @@ void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, DLRBT_Tree
}
-void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys)
+void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys, const bool active)
{
bGPDlayer *gpl;
@@ -1027,7 +1028,9 @@ void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys)
/* for now, just aggregate out all the frames, but only for visible layers */
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if ((gpl->flag & GP_LAYER_HIDE) == 0) {
- gpl_to_keylist(ads, gpl, keys);
+ if ((!active) || ((active) && (gpl->flag & GP_LAYER_SELECT))) {
+ gpl_to_keylist(ads, gpl, keys);
+ }
}
}
}
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index a6ed6643257..b98feac2384 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -183,7 +183,8 @@ void duplicate_fcurve_keys(FCurve *fcu)
/* Various Tools */
/* Basic F-Curve 'cleanup' function that removes 'double points' and unnecessary keyframes on linear-segments only
- * optionally clears up curve if one keyframe with default value remains */
+ * optionally clears up curve if one keyframe with default value remains
+ */
void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, bool cleardefault)
{
FCurve *fcu = (FCurve *)ale->key_data;
@@ -206,7 +207,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
/* now insert first keyframe, as it should be ok */
bezt = old_bezts;
- insert_vert_fcurve(fcu, bezt->vec[1][0], bezt->vec[1][1], BEZKEYTYPE(bezt), 0);
+ insert_bezt_fcurve(fcu, bezt, 0);
if (!(bezt->f2 & SELECT)) {
lastb = fcu->bezt;
lastb->f1 = lastb->f2 = lastb->f3 = 0;
@@ -235,7 +236,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
cur[0] = bezt->vec[1][0]; cur[1] = bezt->vec[1][1];
if (!(bezt->f2 & SELECT)) {
- insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0);
+ insert_bezt_fcurve(fcu, bezt, 0);
lastb = (fcu->bezt + (fcu->totvert - 1));
lastb->f1 = lastb->f2 = lastb->f3 = 0;
continue;
@@ -254,7 +255,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
if (cur[1] > next[1]) {
if (IS_EQT(cur[1], prev[1], thresh) == 0) {
/* add new keyframe */
- insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0);
+ insert_bezt_fcurve(fcu, bezt, 0);
}
}
}
@@ -262,7 +263,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
/* only add if values are a considerable distance apart */
if (IS_EQT(cur[1], prev[1], thresh) == 0) {
/* add new keyframe */
- insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0);
+ insert_bezt_fcurve(fcu, bezt, 0);
}
}
}
@@ -271,19 +272,19 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
if (beztn) {
/* does current have same value as previous and next? */
if (IS_EQT(cur[1], prev[1], thresh) == 0) {
- /* add new keyframe*/
- insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0);
+ /* add new keyframe */
+ insert_bezt_fcurve(fcu, bezt, 0);
}
else if (IS_EQT(cur[1], next[1], thresh) == 0) {
/* add new keyframe */
- insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0);
+ insert_bezt_fcurve(fcu, bezt, 0);
}
}
else {
/* add if value doesn't equal that of previous */
if (IS_EQT(cur[1], prev[1], thresh) == 0) {
/* add new keyframe */
- insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0);
+ insert_bezt_fcurve(fcu, bezt, 0);
}
}
}
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index ae2e7339c66..7602bccc48c 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -426,7 +426,7 @@ static EditBone *get_nearest_editbonepoint(
if (use_cycle) {
static int last_mval[2] = {-100, -100};
- if (vc->v3d->drawtype > OB_WIRE) {
+ if (vc->v3d->shading.type > OB_WIRE) {
do_nearest = true;
if (len_manhattan_v2v2_int(vc->mval, last_mval) < 3) {
do_nearest = false;
@@ -435,7 +435,7 @@ static EditBone *get_nearest_editbonepoint(
copy_v2_v2_int(last_mval, vc->mval);
}
else {
- if (vc->v3d->drawtype > OB_WIRE) {
+ if (vc->v3d->shading.type > OB_WIRE) {
do_nearest = true;
}
}
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index 02d45a4e041..2b28b76bcf6 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -681,7 +681,7 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm)
/* so all users of this armature should get rebuilt */
for (obt = bmain->object.first; obt; obt = obt->id.next) {
if (obt->data == arm) {
- BKE_pose_rebuild(obt, arm);
+ BKE_pose_rebuild(bmain, obt, arm, true);
}
}
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index a9ba8c405ba..a2cd3c57101 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -70,6 +70,15 @@
#include "armature_intern.h"
+
+#define DEBUG_TIME
+
+#include "PIL_time.h"
+#ifdef DEBUG_TIME
+# include "PIL_time_utildefines.h"
+#endif
+
+
/* matches logic with ED_operator_posemode_context() */
Object *ED_pose_object_from_context(bContext *C)
{
@@ -256,10 +265,18 @@ static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
+#ifdef DEBUG_TIME
+ TIMEIT_START(recalc_pose_paths);
+#endif
+
/* calculate the bones that now have motionpaths... */
/* TODO: only make for the selected bones? */
ED_pose_recalculate_paths(C, scene, ob);
+#ifdef DEBUG_TIME
+ TIMEIT_END(recalc_pose_paths);
+#endif
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
@@ -287,7 +304,8 @@ void POSE_OT_paths_calculate(wmOperatorType *ot)
RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End",
"Last frame to calculate bone paths on", MINFRAME, MAXFRAME / 2.0);
- RNA_def_enum(ot->srna, "bake_location", rna_enum_motionpath_bake_location_items, 0,
+ RNA_def_enum(ot->srna, "bake_location", rna_enum_motionpath_bake_location_items,
+ MOTIONPATH_BAKE_HEADS,
"Bake Location",
"Which point on the bones is used when calculating paths");
}
@@ -364,6 +382,9 @@ static void ED_pose_clear_paths(Object *ob, bool only_selected)
/* if nothing was skipped, there should be no paths left! */
if (skipped == false)
ob->pose->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS;
+
+ /* tag armature object for copy on write - so removed paths don't still show */
+ DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
}
/* operator callback - wrapper for the backend function */
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 1d7a9ac46c7..f7d54e3bc4f 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -6260,12 +6260,12 @@ static int match_texture_space_exec(bContext *C, wmOperator *UNUSED(op))
float min[3], max[3], size[3], loc[3];
int a;
- if (object->curve_cache == NULL) {
+ if (object->runtime.curve_cache == NULL) {
BKE_displist_make_curveTypes(depsgraph, scene, object, false);
}
INIT_MINMAX(min, max);
- BKE_displist_minmax(&object->curve_cache->disp, min, max);
+ BKE_displist_minmax(&object->runtime.curve_cache->disp, min, max);
mid_v3_v3v3(loc, min, max);
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 90f9b2e0569..dd0430f4f65 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -387,17 +387,17 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS
float color[3];
UI_GetThemeColor3fv(TH_WIRE, color);
- Gwn_Batch *sphere = GPU_batch_preset_sphere(0);
- GWN_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
- GWN_batch_uniform_3fv(sphere, "color", color);
+ GPUBatch *sphere = GPU_batch_preset_sphere(0);
+ GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
+ GPU_batch_uniform_3fv(sphere, "color", color);
/* scale to edit-mode space */
- gpuPushMatrix();
- gpuMultMatrix(obedit->obmat);
+ GPU_matrix_push();
+ GPU_matrix_mul(obedit->obmat);
BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
- gpuTranslate3f(
+ GPU_matrix_translate_3f(
selem->location_local[0] - location_prev[0],
selem->location_local[1] - location_prev[1],
selem->location_local[2] - location_prev[2]);
@@ -405,15 +405,15 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS
const float radius = stroke_elem_radius(cdd, selem);
- gpuPushMatrix();
- gpuScaleUniform(radius);
- GWN_batch_draw(sphere);
- gpuPopMatrix();
+ GPU_matrix_push();
+ GPU_matrix_scale_1f(radius);
+ GPU_batch_draw(sphere);
+ GPU_matrix_pop();
location_prev = selem->location_local;
}
- gpuPopMatrix();
+ GPU_matrix_pop();
}
if (stroke_len > 1) {
@@ -430,8 +430,8 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS
}
{
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
GPU_depth_test(false);
@@ -440,7 +440,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS
GPU_line_width(3.0f);
imm_cpack(0x0);
- immBegin(GWN_PRIM_LINE_STRIP, stroke_len);
+ immBegin(GPU_PRIM_LINE_STRIP, stroke_len);
for (int i = 0; i < stroke_len; i++) {
immVertex3fv(pos, coord_array[i]);
}
@@ -449,7 +449,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS
GPU_line_width(1.0f);
imm_cpack(0xffffffff);
- immBegin(GWN_PRIM_LINE_STRIP, stroke_len);
+ immBegin(GPU_PRIM_LINE_STRIP, stroke_len);
for (int i = 0; i < stroke_len; i++) {
immVertex3fv(pos, coord_array[i]);
}
@@ -1095,7 +1095,7 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
else {
if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) &&
- (v3d->drawtype > OB_WIRE))
+ (v3d->shading.type > OB_WIRE))
{
/* needed or else the draw matrix can be incorrect */
view3d_operator_needs_opengl(C);
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index 0e09ef6f583..910b61cbdd8 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -536,6 +536,16 @@ set(ICON_NAMES
# This section is maintained by the updating script, keep BEGIN/END comments.
set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
# BEGIN ICON_GEOM_NAMES
+ brush.gpencil.draw.eraser_hard
+ brush.gpencil.draw.eraser_soft
+ brush.gpencil.draw.eraser_stroke
+ brush.gpencil.draw_block
+ brush.gpencil.draw_fill
+ brush.gpencil.draw_ink
+ brush.gpencil.draw_marker
+ brush.gpencil.draw_noise
+ brush.gpencil.draw_pen
+ brush.gpencil.draw_pencil
brush.paint_texture.airbrush
brush.paint_texture.clone
brush.paint_texture.draw
@@ -554,6 +564,13 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
brush.paint_weight.lighten
brush.paint_weight.mix
brush.paint_weight.multiply
+ brush.particle.add
+ brush.particle.comb
+ brush.particle.cut
+ brush.particle.length
+ brush.particle.puff
+ brush.particle.smooth
+ brush.particle.weight
brush.sculpt.blob
brush.sculpt.clay
brush.sculpt.clay_strips
@@ -583,6 +600,24 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
ops.generic.select_border
ops.generic.select_circle
ops.generic.select_lasso
+ ops.gpencil.draw
+ ops.gpencil.draw.eraser
+ ops.gpencil.draw.line
+ ops.gpencil.draw.poly
+ ops.gpencil.edit_bend
+ ops.gpencil.edit_mirror
+ ops.gpencil.edit_shear
+ ops.gpencil.edit_to_sphere
+ ops.gpencil.sculpt_clone
+ ops.gpencil.sculpt_grab
+ ops.gpencil.sculpt_pinch
+ ops.gpencil.sculpt_push
+ ops.gpencil.sculpt_randomize
+ ops.gpencil.sculpt_smooth
+ ops.gpencil.sculpt_strength
+ ops.gpencil.sculpt_thickness
+ ops.gpencil.sculpt_twist
+ ops.gpencil.sculpt_weight
ops.mesh.bevel
ops.mesh.bisect
ops.mesh.dupli_extrude_cursor
@@ -634,6 +669,7 @@ if(WITH_BLENDER)
# blends
data_to_c_simple(../../../../release/datafiles/preview.blend SRC)
data_to_c_simple(../../../../release/datafiles/preview_cycles.blend SRC)
+ data_to_c_simple(../../../../release/datafiles/preview_grease_pencil.blend SRC)
# images
data_to_c_simple(../../../../release/datafiles/splash.png SRC)
@@ -689,6 +725,29 @@ if(WITH_BLENDER)
data_to_c_simple(../../../../release/datafiles/brushicons/twist.png SRC)
data_to_c_simple(../../../../release/datafiles/brushicons/vertexdraw.png SRC)
+ # grease pencil sculpt
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_smooth.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_thickness.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_strength.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_grab.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_push.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_twist.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_pinch.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_randomize.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_clone.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_weight.png SRC)
+
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_pencil.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_pen.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_ink.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_inknoise.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_block.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_marker.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_fill.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_erase_soft.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_erase_hard.png SRC)
+ data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_erase_stroke.png SRC)
+
endif()
data_to_c_simple(../../../../release/datafiles/startup.blend SRC)
diff --git a/source/blender/editors/gizmo_library/CMakeLists.txt b/source/blender/editors/gizmo_library/CMakeLists.txt
index 389820240e2..e1ea5c22ce5 100644
--- a/source/blender/editors/gizmo_library/CMakeLists.txt
+++ b/source/blender/editors/gizmo_library/CMakeLists.txt
@@ -47,6 +47,7 @@ set(SRC
geometry/geom_dial_gizmo.c
gizmo_types/arrow2d_gizmo.c
gizmo_types/arrow3d_gizmo.c
+ gizmo_types/blank3d_gizmo.c
gizmo_types/button2d_gizmo.c
gizmo_types/cage2d_gizmo.c
gizmo_types/cage3d_gizmo.c
diff --git a/source/blender/editors/gizmo_library/gizmo_draw_utils.c b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
index aaaee182c71..5ccb1fa1f6d 100644
--- a/source/blender/editors/gizmo_library/gizmo_draw_utils.c
+++ b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
@@ -64,31 +64,31 @@ void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info, const bool UNUSED(sel
/* TODO store the Batches inside the GizmoGeomInfo and updated it when geom changes
* So we don't need to re-created and discard it every time */
- Gwn_VertBuf *vbo;
- Gwn_IndexBuf *el;
- Gwn_Batch *batch;
- Gwn_IndexBufBuilder elb = {0};
+ GPUVertBuf *vbo;
+ GPUIndexBuf *el;
+ GPUBatch *batch;
+ GPUIndexBufBuilder elb = {0};
- Gwn_VertFormat format = {0};
- uint pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat format = {0};
+ uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
/* Elements */
- GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, info->ntris, info->nverts);
+ GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, info->ntris, info->nverts);
for (int i = 0; i < info->ntris; ++i) {
const unsigned short *idx = &info->indices[i * 3];
- GWN_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]);
+ GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]);
}
- el = GWN_indexbuf_build(&elb);
+ el = GPU_indexbuf_build(&elb);
- vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, info->nverts);
+ vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, info->nverts);
- GWN_vertbuf_attr_fill(vbo, pos_id, info->verts);
+ GPU_vertbuf_attr_fill(vbo, pos_id, info->verts);
- batch = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, el, GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ batch = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, el, GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
- GWN_batch_uniform_4fv(batch, "color", color);
+ GPU_batch_uniform_4fv(batch, "color", color);
/* We may want to re-visit this, for now disable
* since it causes issues leaving the GL state modified. */
@@ -97,7 +97,7 @@ void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info, const bool UNUSED(sel
GPU_depth_test(true);
#endif
- GWN_batch_draw(batch);
+ GPU_batch_draw(batch);
#if 0
GPU_depth_test(false);
@@ -105,7 +105,7 @@ void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info, const bool UNUSED(sel
#endif
- GWN_batch_discard(batch);
+ GPU_batch_discard(batch);
}
void wm_gizmo_vec_draw(
diff --git a/source/blender/editors/gizmo_library/gizmo_library_intern.h b/source/blender/editors/gizmo_library/gizmo_library_intern.h
index f1689ee93db..f5584d86847 100644
--- a/source/blender/editors/gizmo_library/gizmo_library_intern.h
+++ b/source/blender/editors/gizmo_library/gizmo_library_intern.h
@@ -76,25 +76,25 @@ float gizmo_value_from_offset(
const bool constrained, const bool inverted, const bool use_precision);
void gizmo_property_data_update(
- struct wmGizmo *mpr, GizmoCommonData *data, wmGizmoProperty *mpr_prop,
+ struct wmGizmo *gz, GizmoCommonData *data, wmGizmoProperty *gz_prop,
const bool constrained, const bool inverted);
void gizmo_property_value_reset(
- bContext *C, const struct wmGizmo *mpr, GizmoInteraction *inter, wmGizmoProperty *mpr_prop);
+ bContext *C, const struct wmGizmo *gz, GizmoInteraction *inter, wmGizmoProperty *gz_prop);
/* -------------------------------------------------------------------- */
void gizmo_color_get(
- const struct wmGizmo *mpr, const bool highlight,
+ const struct wmGizmo *gz, const bool highlight,
float r_color[4]);
bool gizmo_window_project_2d(
- bContext *C, const struct wmGizmo *mpr, const float mval[2], int axis, bool use_offset,
+ bContext *C, const struct wmGizmo *gz, const float mval[2], int axis, bool use_offset,
float r_co[2]);
bool gizmo_window_project_3d(
- bContext *C, const struct wmGizmo *mpr, const float mval[2], bool use_offset,
+ bContext *C, const struct wmGizmo *gz, const float mval[2], bool use_offset,
float r_co[3]);
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/gizmo_library/gizmo_library_presets.c b/source/blender/editors/gizmo_library/gizmo_library_presets.c
index 8a6b92e48d6..ab92905192b 100644
--- a/source/blender/editors/gizmo_library/gizmo_library_presets.c
+++ b/source/blender/editors/gizmo_library/gizmo_library_presets.c
@@ -81,23 +81,23 @@ static void single_axis_convert(
* Use for all geometry.
*/
static void ed_gizmo_draw_preset_geometry(
- const struct wmGizmo *mpr, float mat[4][4], int select_id,
+ const struct wmGizmo *gz, float mat[4][4], int select_id,
const GizmoGeomInfo *info)
{
const bool is_select = (select_id != -1);
- const bool is_highlight = is_select && (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
+ const bool is_highlight = is_select && (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
float color[4];
- gizmo_color_get(mpr, is_highlight, color);
+ gizmo_color_get(gz, is_highlight, color);
if (is_select) {
GPU_select_load_id(select_id);
}
- gpuPushMatrix();
- gpuMultMatrix(mat);
+ GPU_matrix_push();
+ GPU_matrix_mul(mat);
wm_gizmo_geometryinfo_draw(info, is_select, color);
- gpuPopMatrix();
+ GPU_matrix_pop();
if (is_select) {
GPU_select_load_id(-1);
@@ -105,44 +105,44 @@ static void ed_gizmo_draw_preset_geometry(
}
void ED_gizmo_draw_preset_box(
- const struct wmGizmo *mpr, float mat[4][4], int select_id)
+ const struct wmGizmo *gz, float mat[4][4], int select_id)
{
- ed_gizmo_draw_preset_geometry(mpr, mat, select_id, &wm_gizmo_geom_data_cube);
+ ed_gizmo_draw_preset_geometry(gz, mat, select_id, &wm_gizmo_geom_data_cube);
}
void ED_gizmo_draw_preset_arrow(
- const struct wmGizmo *mpr, float mat[4][4], int axis, int select_id)
+ const struct wmGizmo *gz, float mat[4][4], int axis, int select_id)
{
float mat_rotate[4][4];
single_axis_convert(OB_POSZ, mat, axis, mat_rotate);
- ed_gizmo_draw_preset_geometry(mpr, mat_rotate, select_id, &wm_gizmo_geom_data_arrow);
+ ed_gizmo_draw_preset_geometry(gz, mat_rotate, select_id, &wm_gizmo_geom_data_arrow);
}
void ED_gizmo_draw_preset_circle(
- const struct wmGizmo *mpr, float mat[4][4], int axis, int select_id)
+ const struct wmGizmo *gz, float mat[4][4], int axis, int select_id)
{
float mat_rotate[4][4];
single_axis_convert(OB_POSZ, mat, axis, mat_rotate);
- ed_gizmo_draw_preset_geometry(mpr, mat_rotate, select_id, &wm_gizmo_geom_data_dial);
+ ed_gizmo_draw_preset_geometry(gz, mat_rotate, select_id, &wm_gizmo_geom_data_dial);
}
void ED_gizmo_draw_preset_facemap(
- const bContext *C, const struct wmGizmo *mpr, struct Scene *scene, Object *ob, const int facemap, int select_id)
+ const bContext *C, const struct wmGizmo *gz, struct Scene *scene, Object *ob, const int facemap, int select_id)
{
const bool is_select = (select_id != -1);
- const bool is_highlight = is_select && (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
+ const bool is_highlight = is_select && (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
float color[4];
- gizmo_color_get(mpr, is_highlight, color);
+ gizmo_color_get(gz, is_highlight, color);
if (is_select) {
GPU_select_load_id(select_id);
}
- gpuPushMatrix();
- gpuMultMatrix(ob->obmat);
+ GPU_matrix_push();
+ GPU_matrix_mul(ob->obmat);
ED_draw_object_facemap(CTX_data_depsgraph(C), scene, ob, color, facemap);
- gpuPopMatrix();
+ GPU_matrix_pop();
if (is_select) {
GPU_select_load_id(-1);
diff --git a/source/blender/editors/gizmo_library/gizmo_library_utils.c b/source/blender/editors/gizmo_library/gizmo_library_utils.c
index 6e6bc2ed824..07c230c5503 100644
--- a/source/blender/editors/gizmo_library/gizmo_library_utils.c
+++ b/source/blender/editors/gizmo_library/gizmo_library_utils.c
@@ -107,13 +107,13 @@ float gizmo_value_from_offset(
}
void gizmo_property_data_update(
- wmGizmo *mpr, GizmoCommonData *data, wmGizmoProperty *mpr_prop,
+ wmGizmo *gz, GizmoCommonData *data, wmGizmoProperty *gz_prop,
const bool constrained, const bool inverted)
{
- if (mpr_prop->custom_func.value_get_fn != NULL) {
+ if (gz_prop->custom_func.value_get_fn != NULL) {
/* pass */
}
- else if (mpr_prop->prop != NULL) {
+ else if (gz_prop->prop != NULL) {
/* pass */
}
else {
@@ -121,12 +121,12 @@ void gizmo_property_data_update(
return;
}
- float value = WM_gizmo_target_property_value_get(mpr, mpr_prop);
+ float value = WM_gizmo_target_property_value_get(gz, gz_prop);
if (constrained) {
if ((data->flag & GIZMO_CUSTOM_RANGE_SET) == 0) {
float range[2];
- if (WM_gizmo_target_property_range_get(mpr, mpr_prop, range)) {
+ if (WM_gizmo_target_property_range_get(gz, gz_prop, range)) {
data->range = range[1] - range[0];
data->min = range[0];
}
@@ -142,23 +142,23 @@ void gizmo_property_data_update(
}
void gizmo_property_value_reset(
- bContext *C, const wmGizmo *mpr, GizmoInteraction *inter,
- wmGizmoProperty *mpr_prop)
+ bContext *C, const wmGizmo *gz, GizmoInteraction *inter,
+ wmGizmoProperty *gz_prop)
{
- WM_gizmo_target_property_value_set(C, mpr, mpr_prop, inter->init_value);
+ WM_gizmo_target_property_value_set(C, gz, gz_prop, inter->init_value);
}
/* -------------------------------------------------------------------- */
void gizmo_color_get(
- const wmGizmo *mpr, const bool highlight,
+ const wmGizmo *gz, const bool highlight,
float r_col[4])
{
- if (highlight && !(mpr->flag & WM_GIZMO_DRAW_HOVER)) {
- copy_v4_v4(r_col, mpr->color_hi);
+ if (highlight && !(gz->flag & WM_GIZMO_DRAW_HOVER)) {
+ copy_v4_v4(r_col, gz->color_hi);
}
else {
- copy_v4_v4(r_col, mpr->color);
+ copy_v4_v4(r_col, gz->color);
}
}
@@ -169,7 +169,7 @@ void gizmo_color_get(
* Both 2D & 3D supported, use so we can use 2D gizmos in the 3D view.
*/
bool gizmo_window_project_2d(
- bContext *C, const struct wmGizmo *mpr, const float mval[2], int axis, bool use_offset,
+ bContext *C, const struct wmGizmo *gz, const float mval[2], int axis, bool use_offset,
float r_co[2])
{
float mat[4][4];
@@ -180,11 +180,11 @@ bool gizmo_window_project_2d(
unit_m4(mat_identity);
params.matrix_offset = mat_identity;
}
- WM_gizmo_calc_matrix_final_params(mpr, &params, mat);
+ WM_gizmo_calc_matrix_final_params(gz, &params, mat);
}
/* rotate mouse in relation to the center and relocate it */
- if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
+ if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
/* For 3d views, transform 2D mouse pos onto plane. */
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
@@ -221,7 +221,7 @@ bool gizmo_window_project_2d(
}
bool gizmo_window_project_3d(
- bContext *C, const struct wmGizmo *mpr, const float mval[2], bool use_offset,
+ bContext *C, const struct wmGizmo *gz, const float mval[2], bool use_offset,
float r_co[3])
{
float mat[4][4];
@@ -232,10 +232,10 @@ bool gizmo_window_project_3d(
unit_m4(mat_identity);
params.matrix_offset = mat_identity;
}
- WM_gizmo_calc_matrix_final_params(mpr, &params, mat);
+ WM_gizmo_calc_matrix_final_params(gz, &params, mat);
}
- if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
+ if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
/* Note: we might want a custom reference point passed in,
diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c
index dfa2eeeb38b..953e763a33c 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c
@@ -61,31 +61,31 @@
#include "../gizmo_library_intern.h"
-static void arrow2d_draw_geom(wmGizmo *mpr, const float matrix[4][4], const float color[4])
+static void arrow2d_draw_geom(wmGizmo *gz, const float matrix[4][4], const float color[4])
{
const float size = 0.11f;
const float size_breadth = size / 2.0f;
const float size_length = size * 1.7f;
/* Subtract the length so the arrow fits in the hotspot. */
- const float arrow_length = RNA_float_get(mpr->ptr, "length") - size_length;
- const float arrow_angle = RNA_float_get(mpr->ptr, "angle");
+ const float arrow_length = RNA_float_get(gz->ptr, "length") - size_length;
+ const float arrow_angle = RNA_float_get(gz->ptr, "angle");
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- gpuPushMatrix();
- gpuMultMatrix(matrix);
- gpuRotate2D(RAD2DEGF(arrow_angle));
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix);
+ GPU_matrix_rotate_2d(RAD2DEGF(arrow_angle));
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(color);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, 0.0f, 0.0f);
immVertex2f(pos, 0.0f, arrow_length);
immEnd();
- immBegin(GWN_PRIM_TRIS, 3);
+ immBegin(GPU_PRIM_TRIS, 3);
immVertex2f(pos, size_breadth, arrow_length);
immVertex2f(pos, -size_breadth, arrow_length);
immVertex2f(pos, 0.0f, arrow_length + size_length);
@@ -93,63 +93,63 @@ static void arrow2d_draw_geom(wmGizmo *mpr, const float matrix[4][4], const floa
immUnbindProgram();
- gpuPopMatrix();
+ GPU_matrix_pop();
}
-static void gizmo_arrow2d_draw(const bContext *UNUSED(C), wmGizmo *mpr)
+static void gizmo_arrow2d_draw(const bContext *UNUSED(C), wmGizmo *gz)
{
float color[4];
float matrix_final[4][4];
- gizmo_color_get(mpr, mpr->state & WM_GIZMO_STATE_HIGHLIGHT, color);
+ gizmo_color_get(gz, gz->state & WM_GIZMO_STATE_HIGHLIGHT, color);
- GPU_line_width(mpr->line_width);
+ GPU_line_width(gz->line_width);
- WM_gizmo_calc_matrix_final(mpr, matrix_final);
+ WM_gizmo_calc_matrix_final(gz, matrix_final);
GPU_blend(true);
- arrow2d_draw_geom(mpr, matrix_final, color);
+ arrow2d_draw_geom(gz, matrix_final, color);
GPU_blend(false);
- if (mpr->interaction_data) {
- GizmoInteraction *inter = mpr->interaction_data;
+ if (gz->interaction_data) {
+ GizmoInteraction *inter = gz->interaction_data;
GPU_blend(true);
- arrow2d_draw_geom(mpr, inter->init_matrix_final, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f});
+ arrow2d_draw_geom(gz, inter->init_matrix_final, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f});
GPU_blend(false);
}
}
-static void gizmo_arrow2d_setup(wmGizmo *mpr)
+static void gizmo_arrow2d_setup(wmGizmo *gz)
{
- mpr->flag |= WM_GIZMO_DRAW_MODAL;
+ gz->flag |= WM_GIZMO_DRAW_MODAL;
}
static int gizmo_arrow2d_invoke(
- bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *UNUSED(event))
+ bContext *UNUSED(C), wmGizmo *gz, const wmEvent *UNUSED(event))
{
GizmoInteraction *inter = MEM_callocN(sizeof(GizmoInteraction), __func__);
- copy_m4_m4(inter->init_matrix_basis, mpr->matrix_basis);
- WM_gizmo_calc_matrix_final(mpr, inter->init_matrix_final);
+ copy_m4_m4(inter->init_matrix_basis, gz->matrix_basis);
+ WM_gizmo_calc_matrix_final(gz, inter->init_matrix_final);
- mpr->interaction_data = inter;
+ gz->interaction_data = inter;
return OPERATOR_RUNNING_MODAL;
}
static int gizmo_arrow2d_test_select(
- bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event)
+ bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
{
- const float mval[2] = {event->mval[0], event->mval[1]};
- const float arrow_length = RNA_float_get(mpr->ptr, "length");
- const float arrow_angle = RNA_float_get(mpr->ptr, "angle");
- const float line_len = arrow_length * mpr->scale_final;
+ const float mval_fl[2] = {UNPACK2(mval)};
+ const float arrow_length = RNA_float_get(gz->ptr, "length");
+ const float arrow_angle = RNA_float_get(gz->ptr, "angle");
+ const float line_len = arrow_length * gz->scale_final;
float mval_local[2];
- copy_v2_v2(mval_local, mval);
- sub_v2_v2(mval_local, mpr->matrix_basis[3]);
+ copy_v2_v2(mval_local, mval_fl);
+ sub_v2_v2(mval_local, gz->matrix_basis[3]);
float line[2][2];
line[0][0] = line[0][1] = line[1][0] = 0.0f;
@@ -165,7 +165,7 @@ static int gizmo_arrow2d_test_select(
/* arrow line intersection check */
float isect_1[2], isect_2[2];
const int isect = isect_line_sphere_v2(
- line[0], line[1], mval_local, GIZMO_HOTSPOT + mpr->line_width * 0.5f,
+ line[0], line[1], mval_local, GIZMO_HOTSPOT + gz->line_width * 0.5f,
isect_1, isect_2);
if (isect > 0) {
@@ -197,29 +197,29 @@ static int gizmo_arrow2d_test_select(
*
* \{ */
-static void GIZMO_WT_arrow_2d(wmGizmoType *wt)
+static void GIZMO_GT_arrow_2d(wmGizmoType *gzt)
{
/* identifiers */
- wt->idname = "GIZMO_WT_arrow_2d";
+ gzt->idname = "GIZMO_GT_arrow_2d";
/* api callbacks */
- wt->draw = gizmo_arrow2d_draw;
- wt->setup = gizmo_arrow2d_setup;
- wt->invoke = gizmo_arrow2d_invoke;
- wt->test_select = gizmo_arrow2d_test_select;
+ gzt->draw = gizmo_arrow2d_draw;
+ gzt->setup = gizmo_arrow2d_setup;
+ gzt->invoke = gizmo_arrow2d_invoke;
+ gzt->test_select = gizmo_arrow2d_test_select;
- wt->struct_size = sizeof(wmGizmo);
+ gzt->struct_size = sizeof(wmGizmo);
/* rna */
- RNA_def_float(wt->srna, "length", 1.0f, 0.0f, FLT_MAX, "Arrow Line Length", "", 0.0f, FLT_MAX);
+ RNA_def_float(gzt->srna, "length", 1.0f, 0.0f, FLT_MAX, "Arrow Line Length", "", 0.0f, FLT_MAX);
RNA_def_float_rotation(
- wt->srna, "angle", 0, NULL, DEG2RADF(-360.0f), DEG2RADF(360.0f),
+ gzt->srna, "angle", 0, NULL, DEG2RADF(-360.0f), DEG2RADF(360.0f),
"Roll", "", DEG2RADF(-360.0f), DEG2RADF(360.0f));
}
void ED_gizmotypes_arrow_2d(void)
{
- WM_gizmotype_append(GIZMO_WT_arrow_2d);
+ WM_gizmotype_append(GIZMO_GT_arrow_2d);
}
/** \} */
diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
index 9807a111d26..0f8389af17d 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
@@ -80,9 +80,9 @@ typedef struct ArrowGizmo3D {
/* -------------------------------------------------------------------- */
-static void gizmo_arrow_matrix_basis_get(const wmGizmo *mpr, float r_matrix[4][4])
+static void gizmo_arrow_matrix_basis_get(const wmGizmo *gz, float r_matrix[4][4])
{
- ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr;
+ ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz;
copy_m4_m4(r_matrix, arrow->gizmo.matrix_basis);
madd_v3_v3fl(r_matrix[3], arrow->gizmo.matrix_basis[2], arrow->data.offset);
@@ -90,7 +90,7 @@ static void gizmo_arrow_matrix_basis_get(const wmGizmo *mpr, float r_matrix[4][4
static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const float color[4])
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
bool unbind_shader = true;
const int draw_style = RNA_enum_get(arrow->gizmo.ptr, "draw_style");
const int draw_options = RNA_enum_get(arrow->gizmo.ptr, "draw_options");
@@ -100,7 +100,7 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
if (draw_style == ED_GIZMO_ARROW_STYLE_CROSS) {
immUniformColor4fv(color);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex3f(pos, -1.0f, 0.0f, 0.0f);
immVertex3f(pos, 1.0f, 0.0f, 0.0f);
immVertex3f(pos, 0.0f, -1.0f, 0.0f);
@@ -120,7 +120,7 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
};
GPU_line_width(arrow->gizmo.line_width);
- wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GWN_PRIM_LINE_LOOP);
+ wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GPU_PRIM_LINE_LOOP);
}
else {
#ifdef USE_GIZMO_CUSTOM_ARROWS
@@ -135,7 +135,7 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
if (draw_options & ED_GIZMO_ARROW_DRAW_FLAG_STEM) {
GPU_line_width(arrow->gizmo.line_width);
- wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GWN_PRIM_LINE_STRIP);
+ wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GPU_PRIM_LINE_STRIP);
}
else {
immUniformColor4fv(color);
@@ -143,15 +143,15 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
/* *** draw arrow head *** */
- gpuPushMatrix();
+ GPU_matrix_push();
if (draw_style == ED_GIZMO_ARROW_STYLE_BOX) {
const float size = 0.05f;
/* translate to line end with some extra offset so box starts exactly where line ends */
- gpuTranslate3f(0.0f, 0.0f, arrow_length + size);
+ GPU_matrix_translate_3f(0.0f, 0.0f, arrow_length + size);
/* scale down to box size */
- gpuScale3f(size, size, size);
+ GPU_matrix_scale_3f(size, size, size);
/* draw cube */
immUnbindProgram();
@@ -165,13 +165,13 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
const float width = 0.06f;
/* translate to line end */
- gpuTranslate3f(0.0f, 0.0f, arrow_length);
+ GPU_matrix_translate_3f(0.0f, 0.0f, arrow_length);
imm_draw_circle_fill_3d(pos, 0.0, 0.0, width, 8);
imm_draw_cylinder_fill_3d(pos, width, 0.0, len, 8, 1);
}
- gpuPopMatrix();
+ GPU_matrix_pop();
#endif /* USE_GIZMO_CUSTOM_ARROWS */
}
@@ -182,48 +182,48 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool highlight)
{
- wmGizmo *mpr = &arrow->gizmo;
+ wmGizmo *gz = &arrow->gizmo;
float color[4];
float matrix_final[4][4];
- gizmo_color_get(mpr, highlight, color);
+ gizmo_color_get(gz, highlight, color);
- WM_gizmo_calc_matrix_final(mpr, matrix_final);
+ WM_gizmo_calc_matrix_final(gz, matrix_final);
- gpuPushMatrix();
- gpuMultMatrix(matrix_final);
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix_final);
GPU_blend(true);
arrow_draw_geom(arrow, select, color);
GPU_blend(false);
- gpuPopMatrix();
+ GPU_matrix_pop();
- if (mpr->interaction_data) {
- GizmoInteraction *inter = mpr->interaction_data;
+ if (gz->interaction_data) {
+ GizmoInteraction *inter = gz->interaction_data;
- gpuPushMatrix();
- gpuMultMatrix(inter->init_matrix_final);
+ GPU_matrix_push();
+ GPU_matrix_mul(inter->init_matrix_final);
GPU_blend(true);
arrow_draw_geom(arrow, select, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f});
GPU_blend(false);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
static void gizmo_arrow_draw_select(
- const bContext *UNUSED(C), wmGizmo *mpr,
+ const bContext *UNUSED(C), wmGizmo *gz,
int select_id)
{
GPU_select_load_id(select_id);
- arrow_draw_intern((ArrowGizmo3D *)mpr, true, false);
+ arrow_draw_intern((ArrowGizmo3D *)gz, true, false);
}
-static void gizmo_arrow_draw(const bContext *UNUSED(C), wmGizmo *mpr)
+static void gizmo_arrow_draw(const bContext *UNUSED(C), wmGizmo *gz)
{
- arrow_draw_intern((ArrowGizmo3D *)mpr, false, (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0);
+ arrow_draw_intern((ArrowGizmo3D *)gz, false, (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0);
}
/**
@@ -231,11 +231,11 @@ static void gizmo_arrow_draw(const bContext *UNUSED(C), wmGizmo *mpr)
* meaning the range will not be offset by min value first.
*/
static int gizmo_arrow_modal(
- bContext *C, wmGizmo *mpr, const wmEvent *event,
+ bContext *C, wmGizmo *gz, const wmEvent *event,
eWM_GizmoFlagTweak tweak_flag)
{
- ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr;
- GizmoInteraction *inter = mpr->interaction_data;
+ ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz;
+ GizmoInteraction *inter = gz->interaction_data;
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = ar->regiondata;
@@ -299,19 +299,19 @@ static int gizmo_arrow_modal(
GizmoCommonData *data = &arrow->data;
const float ofs_new = facdir * len_v3(offset);
- wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset");
+ wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
/* set the property for the operator and call its modal function */
- if (WM_gizmo_target_property_is_valid(mpr_prop)) {
+ if (WM_gizmo_target_property_is_valid(gz_prop)) {
const int transform_flag = RNA_enum_get(arrow->gizmo.ptr, "transform");
const bool constrained = (transform_flag & ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED) != 0;
const bool inverted = (transform_flag & ED_GIZMO_ARROW_XFORM_FLAG_INVERTED) != 0;
const bool use_precision = (tweak_flag & WM_GIZMO_TWEAK_PRECISE) != 0;
float value = gizmo_value_from_offset(data, inter, ofs_new, constrained, inverted, use_precision);
- WM_gizmo_target_property_value_set(C, mpr, mpr_prop, value);
+ WM_gizmo_target_property_value_set(C, gz, gz_prop, value);
/* get clamped value */
- value = WM_gizmo_target_property_value_get(mpr, mpr_prop);
+ value = WM_gizmo_target_property_value_get(gz, gz_prop);
data->offset = gizmo_offset_from_value(data, value, constrained, inverted);
}
@@ -326,9 +326,9 @@ static int gizmo_arrow_modal(
return OPERATOR_RUNNING_MODAL;
}
-static void gizmo_arrow_setup(wmGizmo *mpr)
+static void gizmo_arrow_setup(wmGizmo *gz)
{
- ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr;
+ ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz;
arrow->gizmo.flag |= WM_GIZMO_DRAW_MODAL;
@@ -336,15 +336,15 @@ static void gizmo_arrow_setup(wmGizmo *mpr)
}
static int gizmo_arrow_invoke(
- bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event)
+ bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event)
{
- ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr;
+ ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz;
GizmoInteraction *inter = MEM_callocN(sizeof(GizmoInteraction), __func__);
- wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset");
+ wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
/* Some gizmos don't use properties. */
- if (WM_gizmo_target_property_is_valid(mpr_prop)) {
- inter->init_value = WM_gizmo_target_property_value_get(mpr, mpr_prop);
+ if (WM_gizmo_target_property_is_valid(gz_prop)) {
+ inter->init_value = WM_gizmo_target_property_value_get(gz, gz_prop);
}
inter->init_offset = arrow->data.offset;
@@ -352,42 +352,42 @@ static int gizmo_arrow_invoke(
inter->init_mval[0] = event->mval[0];
inter->init_mval[1] = event->mval[1];
- gizmo_arrow_matrix_basis_get(mpr, inter->init_matrix_basis);
- WM_gizmo_calc_matrix_final(mpr, inter->init_matrix_final);
+ gizmo_arrow_matrix_basis_get(gz, inter->init_matrix_basis);
+ WM_gizmo_calc_matrix_final(gz, inter->init_matrix_final);
- mpr->interaction_data = inter;
+ gz->interaction_data = inter;
return OPERATOR_RUNNING_MODAL;
}
-static void gizmo_arrow_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop)
+static void gizmo_arrow_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop)
{
- ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr;
+ ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz;
const int transform_flag = RNA_enum_get(arrow->gizmo.ptr, "transform");
const bool constrained = (transform_flag & ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED) != 0;
const bool inverted = (transform_flag & ED_GIZMO_ARROW_XFORM_FLAG_INVERTED) != 0;
- gizmo_property_data_update(mpr, &arrow->data, mpr_prop, constrained, inverted);
+ gizmo_property_data_update(gz, &arrow->data, gz_prop, constrained, inverted);
}
-static void gizmo_arrow_exit(bContext *C, wmGizmo *mpr, const bool cancel)
+static void gizmo_arrow_exit(bContext *C, wmGizmo *gz, const bool cancel)
{
- ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr;
+ ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz;
GizmoCommonData *data = &arrow->data;
- wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset");
- const bool is_prop_valid = WM_gizmo_target_property_is_valid(mpr_prop);
+ wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
+ const bool is_prop_valid = WM_gizmo_target_property_is_valid(gz_prop);
if (!cancel) {
/* Assign incase applying the opetration needs an updated offset
* editmesh bisect needs this. */
if (is_prop_valid) {
- data->offset = WM_gizmo_target_property_value_get(mpr, mpr_prop);
+ data->offset = WM_gizmo_target_property_value_get(gz, gz_prop);
}
return;
}
- GizmoInteraction *inter = mpr->interaction_data;
+ GizmoInteraction *inter = gz->interaction_data;
if (is_prop_valid) {
- gizmo_property_value_reset(C, mpr, inter, mpr_prop);
+ gizmo_property_value_reset(C, gz, inter, gz_prop);
}
data->offset = inter->init_offset;
}
@@ -403,12 +403,12 @@ static void gizmo_arrow_exit(bContext *C, wmGizmo *mpr, const bool cancel)
*
* \note Needs to be called before WM_gizmo_target_property_def_rna!
*/
-void ED_gizmo_arrow3d_set_ui_range(wmGizmo *mpr, const float min, const float max)
+void ED_gizmo_arrow3d_set_ui_range(wmGizmo *gz, const float min, const float max)
{
- ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr;
+ ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz;
BLI_assert(min < max);
- BLI_assert(!(WM_gizmo_target_property_is_valid(WM_gizmo_target_property_find(mpr, "offset")) &&
+ BLI_assert(!(WM_gizmo_target_property_is_valid(WM_gizmo_target_property_find(gz, "offset")) &&
"Make sure this function is called before WM_gizmo_target_property_def_rna"));
arrow->data.range = max - min;
@@ -421,31 +421,31 @@ void ED_gizmo_arrow3d_set_ui_range(wmGizmo *mpr, const float min, const float ma
*
* \note Needs to be called before WM_gizmo_target_property_def_rna!
*/
-void ED_gizmo_arrow3d_set_range_fac(wmGizmo *mpr, const float range_fac)
+void ED_gizmo_arrow3d_set_range_fac(wmGizmo *gz, const float range_fac)
{
- ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr;
- BLI_assert(!(WM_gizmo_target_property_is_valid(WM_gizmo_target_property_find(mpr, "offset")) &&
+ ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz;
+ BLI_assert(!(WM_gizmo_target_property_is_valid(WM_gizmo_target_property_find(gz, "offset")) &&
"Make sure this function is called before WM_gizmo_target_property_def_rna"));
arrow->data.range_fac = range_fac;
}
-static void GIZMO_WT_arrow_3d(wmGizmoType *wt)
+static void GIZMO_GT_arrow_3d(wmGizmoType *gzt)
{
/* identifiers */
- wt->idname = "GIZMO_WT_arrow_3d";
+ gzt->idname = "GIZMO_GT_arrow_3d";
/* api callbacks */
- wt->draw = gizmo_arrow_draw;
- wt->draw_select = gizmo_arrow_draw_select;
- wt->matrix_basis_get = gizmo_arrow_matrix_basis_get;
- wt->modal = gizmo_arrow_modal;
- wt->setup = gizmo_arrow_setup;
- wt->invoke = gizmo_arrow_invoke;
- wt->property_update = gizmo_arrow_property_update;
- wt->exit = gizmo_arrow_exit;
+ gzt->draw = gizmo_arrow_draw;
+ gzt->draw_select = gizmo_arrow_draw_select;
+ gzt->matrix_basis_get = gizmo_arrow_matrix_basis_get;
+ gzt->modal = gizmo_arrow_modal;
+ gzt->setup = gizmo_arrow_setup;
+ gzt->invoke = gizmo_arrow_invoke;
+ gzt->property_update = gizmo_arrow_property_update;
+ gzt->exit = gizmo_arrow_exit;
- wt->struct_size = sizeof(ArrowGizmo3D);
+ gzt->struct_size = sizeof(ArrowGizmo3D);
/* rna */
static EnumPropertyItem rna_enum_draw_style_items[] = {
@@ -466,27 +466,27 @@ static void GIZMO_WT_arrow_3d(wmGizmoType *wt)
};
RNA_def_enum(
- wt->srna, "draw_style", rna_enum_draw_style_items,
+ gzt->srna, "draw_style", rna_enum_draw_style_items,
ED_GIZMO_ARROW_STYLE_NORMAL,
"Draw Style", "");
RNA_def_enum_flag(
- wt->srna, "draw_options", rna_enum_draw_options_items,
+ gzt->srna, "draw_options", rna_enum_draw_options_items,
ED_GIZMO_ARROW_DRAW_FLAG_STEM,
"Draw Options", "");
RNA_def_enum_flag(
- wt->srna, "transform", rna_enum_transform_items,
+ gzt->srna, "transform", rna_enum_transform_items,
0,
"Transform", "");
- RNA_def_float(wt->srna, "length", 1.0f, 0.0f, FLT_MAX, "Arrow Line Length", "", 0.0f, FLT_MAX);
- RNA_def_float_vector(wt->srna, "aspect", 2, NULL, 0, FLT_MAX, "Aspect", "Cone/box style only", 0.0f, FLT_MAX);
+ RNA_def_float(gzt->srna, "length", 1.0f, 0.0f, FLT_MAX, "Arrow Line Length", "", 0.0f, FLT_MAX);
+ RNA_def_float_vector(gzt->srna, "aspect", 2, NULL, 0, FLT_MAX, "Aspect", "Cone/box style only", 0.0f, FLT_MAX);
- WM_gizmotype_target_property_def(wt, "offset", PROP_FLOAT, 1);
+ WM_gizmotype_target_property_def(gzt, "offset", PROP_FLOAT, 1);
}
void ED_gizmotypes_arrow_3d(void)
{
- WM_gizmotype_append(GIZMO_WT_arrow_3d);
+ WM_gizmotype_append(GIZMO_GT_arrow_3d);
}
/** \} */
diff --git a/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c
new file mode 100644
index 00000000000..0c67e8c606d
--- /dev/null
+++ b/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c
@@ -0,0 +1,89 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blank3d_gizmo.c
+ * \ingroup wm
+ *
+ * \name Blank Gizmo
+ *
+ * \brief Gizmo to use as a fallback (catch events).
+ */
+
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+
+#include "ED_view3d.h"
+#include "ED_gizmo_library.h"
+
+#include "WM_types.h"
+#include "WM_api.h"
+
+/* own includes */
+#include "../gizmo_geometry.h"
+#include "../gizmo_library_intern.h"
+
+
+static void gizmo_blank_draw(const bContext *UNUSED(C), wmGizmo *UNUSED(gz))
+{
+ /* pass */
+}
+
+static int gizmo_blank_invoke(
+ bContext *UNUSED(C), wmGizmo *UNUSED(gz), const wmEvent *UNUSED(event))
+{
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int gizmo_blank_test_select(
+ bContext *UNUSED(C), wmGizmo *UNUSED(gz), const int UNUSED(mval[2]))
+{
+ return 0;
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Blank Gizmo API
+ *
+ * \{ */
+
+static void GIZMO_GT_blank_3d(wmGizmoType *gzt)
+{
+ /* identifiers */
+ gzt->idname = "GIZMO_GT_blank_3d";
+
+ /* api callbacks */
+ gzt->draw = gizmo_blank_draw;
+ gzt->invoke = gizmo_blank_invoke;
+ gzt->test_select = gizmo_blank_test_select;
+
+ gzt->struct_size = sizeof(wmGizmo);
+}
+
+void ED_gizmotypes_blank_3d(void)
+{
+ WM_gizmotype_append(GIZMO_GT_blank_3d);
+}
+
+/** \} */
diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
index ede070f0bed..dfc0dcd791c 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
@@ -72,7 +72,7 @@ typedef struct ButtonGizmo2D {
bool is_init;
/* Use an icon or shape */
int icon;
- Gwn_Batch *shape_batch[2];
+ GPUBatch *shape_batch[2];
} ButtonGizmo2D;
#define CIRCLE_RESOLUTION 32
@@ -80,12 +80,12 @@ typedef struct ButtonGizmo2D {
/* -------------------------------------------------------------------- */
static void button2d_geom_draw_backdrop(
- const wmGizmo *mpr, const float color[4], const bool select)
+ const wmGizmo *gz, const float color[4], const bool select)
{
- GPU_line_width(mpr->line_width);
+ GPU_line_width(gz->line_width);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -100,24 +100,24 @@ static void button2d_geom_draw_backdrop(
}
static void button2d_draw_intern(
- const bContext *C, wmGizmo *mpr,
+ const bContext *C, wmGizmo *gz,
const bool select, const bool highlight)
{
- ButtonGizmo2D *button = (ButtonGizmo2D *)mpr;
+ ButtonGizmo2D *button = (ButtonGizmo2D *)gz;
- const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
if (button->is_init == false) {
button->is_init = true;
- PropertyRNA *prop = RNA_struct_find_property(mpr->ptr, "icon");
- if (RNA_property_is_set(mpr->ptr, prop)) {
- button->icon = RNA_property_enum_get(mpr->ptr, prop);
+ PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon");
+ if (RNA_property_is_set(gz->ptr, prop)) {
+ button->icon = RNA_property_enum_get(gz->ptr, prop);
}
else {
- prop = RNA_struct_find_property(mpr->ptr, "shape");
- const uint polys_len = RNA_property_string_length(mpr->ptr, prop);
+ prop = RNA_struct_find_property(gz->ptr, "shape");
+ const uint polys_len = RNA_property_string_length(gz->ptr, prop);
/* We shouldn't need the +1, but a NULL char is set. */
char *polys = MEM_mallocN(polys_len + 1, __func__);
- RNA_property_string_get(mpr->ptr, prop, polys);
+ RNA_property_string_get(gz->ptr, prop, polys);
button->shape_batch[0] = GPU_batch_tris_from_poly_2d_encoded((uchar *)polys, polys_len, NULL);
button->shape_batch[1] = GPU_batch_wire_from_poly_2d_encoded((uchar *)polys, polys_len, NULL);
MEM_freeN(polys);
@@ -127,22 +127,22 @@ static void button2d_draw_intern(
float color[4];
float matrix_final[4][4];
- gizmo_color_get(mpr, highlight, color);
- WM_gizmo_calc_matrix_final(mpr, matrix_final);
+ gizmo_color_get(gz, highlight, color);
+ WM_gizmo_calc_matrix_final(gz, matrix_final);
- bool is_3d = (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) != 0;
+ bool is_3d = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) != 0;
if (draw_options & ED_GIZMO_BUTTON_SHOW_HELPLINE) {
float matrix_final_no_offset[4][4];
- WM_gizmo_calc_matrix_final_no_offset(mpr, matrix_final_no_offset);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ WM_gizmo_calc_matrix_final_no_offset(gz, matrix_final_no_offset);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(color);
- GPU_line_width(mpr->line_width);
+ GPU_line_width(gz->line_width);
immUniformColor4fv(color);
- immBegin(GWN_PRIM_LINE_STRIP, 2);
+ immBegin(GPU_PRIM_LINE_STRIP, 2);
immVertex3fv(pos, matrix_final[3]);
immVertex3fv(pos, matrix_final_no_offset[3]);
immEnd();
@@ -150,8 +150,8 @@ static void button2d_draw_intern(
}
bool need_to_pop = true;
- gpuPushMatrix();
- gpuMultMatrix(matrix_final);
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix_final);
if (is_3d) {
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -161,12 +161,12 @@ static void button2d_draw_intern(
mul_m4_m4m4(matrix_align, rv3d->viewmat, matrix_final_unit);
zero_v3(matrix_align[3]);
transpose_m4(matrix_align);
- gpuMultMatrix(matrix_align);
+ GPU_matrix_mul(matrix_align);
}
if (select) {
BLI_assert(is_3d);
- button2d_geom_draw_backdrop(mpr, color, select);
+ button2d_geom_draw_backdrop(gz, color, select);
}
else {
@@ -177,9 +177,9 @@ static void button2d_draw_intern(
GPU_line_width(1.0f);
for (uint i = 0; i < ARRAY_SIZE(button->shape_batch) && button->shape_batch[i]; i++) {
/* Invert line color for wire. */
- GWN_batch_program_set_builtin(button->shape_batch[i], GPU_SHADER_2D_UNIFORM_COLOR);
- GWN_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color));
- GWN_batch_draw(button->shape_batch[i]);
+ GPU_batch_program_set_builtin(button->shape_batch[i], GPU_SHADER_2D_UNIFORM_COLOR);
+ GPU_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color));
+ GPU_batch_draw(button->shape_batch[i]);
if (draw_options & ED_GIZMO_BUTTON_SHOW_OUTLINE) {
color[0] = 1.0f - color[0];
@@ -191,19 +191,19 @@ static void button2d_draw_intern(
GPU_polygon_smooth(true);
}
else if (button->icon != ICON_NONE) {
- button2d_geom_draw_backdrop(mpr, color, select);
+ button2d_geom_draw_backdrop(gz, color, select);
float size[2];
if (is_3d) {
const float fac = 2.0f;
- gpuTranslate2f(-(fac / 2), -(fac / 2));
- gpuScale2f(fac / (ICON_DEFAULT_WIDTH * UI_DPI_FAC), fac / (ICON_DEFAULT_HEIGHT * UI_DPI_FAC));
+ GPU_matrix_translate_2f(-(fac / 2), -(fac / 2));
+ GPU_matrix_scale_2f(fac / (ICON_DEFAULT_WIDTH * UI_DPI_FAC), fac / (ICON_DEFAULT_HEIGHT * UI_DPI_FAC));
size[0] = 1.0f;
size[1] = 1.0f;
}
else {
- size[0] = mpr->matrix_basis[3][0] - (ICON_DEFAULT_WIDTH / 2.0) * UI_DPI_FAC;
- size[1] = mpr->matrix_basis[3][1] - (ICON_DEFAULT_HEIGHT / 2.0) * UI_DPI_FAC;
- gpuPopMatrix();
+ size[0] = gz->matrix_basis[3][0] - (ICON_DEFAULT_WIDTH / 2.0) * UI_DPI_FAC;
+ size[1] = gz->matrix_basis[3][1] - (ICON_DEFAULT_HEIGHT / 2.0) * UI_DPI_FAC;
+ GPU_matrix_pop();
need_to_pop = false;
}
UI_icon_draw(size[0], size[1], button->icon);
@@ -212,44 +212,44 @@ static void button2d_draw_intern(
}
if (need_to_pop) {
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
-static void gizmo_button2d_draw_select(const bContext *C, wmGizmo *mpr, int select_id)
+static void gizmo_button2d_draw_select(const bContext *C, wmGizmo *gz, int select_id)
{
GPU_select_load_id(select_id);
- button2d_draw_intern(C, mpr, true, false);
+ button2d_draw_intern(C, gz, true, false);
}
-static void gizmo_button2d_draw(const bContext *C, wmGizmo *mpr)
+static void gizmo_button2d_draw(const bContext *C, wmGizmo *gz)
{
- const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
+ const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
GPU_blend(true);
- button2d_draw_intern(C, mpr, false, is_highlight);
+ button2d_draw_intern(C, gz, false, is_highlight);
GPU_blend(false);
}
static int gizmo_button2d_test_select(
- bContext *C, wmGizmo *mpr, const wmEvent *event)
+ bContext *C, wmGizmo *gz, const int mval[2])
{
float point_local[2];
if (0) {
/* correct, but unnecessarily slow. */
if (gizmo_window_project_2d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false)
+ C, gz, (const float[2]){UNPACK2(mval)}, 2, true, point_local) == false)
{
return -1;
}
}
else {
- copy_v2_v2(point_local, (float[2]){UNPACK2(event->mval)});
- sub_v2_v2(point_local, mpr->matrix_basis[3]);
- mul_v2_fl(point_local, 1.0f / (mpr->scale_basis * UI_DPI_FAC));
+ copy_v2_v2(point_local, (float[2]){UNPACK2(mval)});
+ sub_v2_v2(point_local, gz->matrix_basis[3]);
+ mul_v2_fl(point_local, 1.0f / (gz->scale_basis * UI_DPI_FAC));
}
- /* The 'mpr->scale_final' is already applied when projecting. */
+ /* The 'gz->scale_final' is already applied when projecting. */
if (len_squared_v2(point_local) < 1.0f) {
return 0;
}
@@ -257,20 +257,20 @@ static int gizmo_button2d_test_select(
return -1;
}
-static int gizmo_button2d_cursor_get(wmGizmo *mpr)
+static int gizmo_button2d_cursor_get(wmGizmo *gz)
{
- if (RNA_boolean_get(mpr->ptr, "show_drag")) {
+ if (RNA_boolean_get(gz->ptr, "show_drag")) {
return BC_NSEW_SCROLLCURSOR;
}
return CURSOR_STD;
}
-static void gizmo_button2d_free(wmGizmo *mpr)
+static void gizmo_button2d_free(wmGizmo *gz)
{
- ButtonGizmo2D *shape = (ButtonGizmo2D *)mpr;
+ ButtonGizmo2D *shape = (ButtonGizmo2D *)gz;
for (uint i = 0; i < ARRAY_SIZE(shape->shape_batch); i++) {
- GWN_BATCH_DISCARD_SAFE(shape->shape_batch[i]);
+ GPU_BATCH_DISCARD_SAFE(shape->shape_batch[i]);
}
}
@@ -281,19 +281,19 @@ static void gizmo_button2d_free(wmGizmo *mpr)
*
* \{ */
-static void GIZMO_WT_button_2d(wmGizmoType *wt)
+static void GIZMO_GT_button_2d(wmGizmoType *gzt)
{
/* identifiers */
- wt->idname = "GIZMO_WT_button_2d";
+ gzt->idname = "GIZMO_GT_button_2d";
/* api callbacks */
- wt->draw = gizmo_button2d_draw;
- wt->draw_select = gizmo_button2d_draw_select;
- wt->test_select = gizmo_button2d_test_select;
- wt->cursor_get = gizmo_button2d_cursor_get;
- wt->free = gizmo_button2d_free;
+ gzt->draw = gizmo_button2d_draw;
+ gzt->draw_select = gizmo_button2d_draw_select;
+ gzt->test_select = gizmo_button2d_test_select;
+ gzt->cursor_get = gizmo_button2d_cursor_get;
+ gzt->free = gizmo_button2d_free;
- wt->struct_size = sizeof(ButtonGizmo2D);
+ gzt->struct_size = sizeof(ButtonGizmo2D);
/* rna */
static EnumPropertyItem rna_enum_draw_options[] = {
@@ -303,21 +303,21 @@ static void GIZMO_WT_button_2d(wmGizmoType *wt)
};
PropertyRNA *prop;
- RNA_def_enum_flag(wt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", "");
+ RNA_def_enum_flag(gzt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", "");
- prop = RNA_def_property(wt->srna, "icon", PROP_ENUM, PROP_NONE);
+ prop = RNA_def_property(gzt->srna, "icon", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_icon_items);
/* Passed to 'GPU_batch_tris_from_poly_2d_encoded' */
- RNA_def_property(wt->srna, "shape", PROP_STRING, PROP_BYTESTRING);
+ RNA_def_property(gzt->srna, "shape", PROP_STRING, PROP_BYTESTRING);
/* Currently only used for cursor display. */
- RNA_def_boolean(wt->srna, "show_drag", true, "Show Drag", "");
+ RNA_def_boolean(gzt->srna, "show_drag", true, "Show Drag", "");
}
void ED_gizmotypes_button_2d(void)
{
- WM_gizmotype_append(GIZMO_WT_button_2d);
+ WM_gizmotype_append(GIZMO_GT_button_2d);
}
/** \} */ // Button Gizmo API
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
index a037727de58..bb9cac595be 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
@@ -68,7 +68,7 @@
#define GIZMO_MARGIN_OFFSET_SCALE 1.5f
static void gizmo_calc_rect_view_scale(
- const wmGizmo *mpr, const float dims[2], float scale[2])
+ const wmGizmo *gz, const float dims[2], float scale[2])
{
float matrix_final_no_offset[4][4];
float asp[2] = {1.0f, 1.0f};
@@ -79,9 +79,9 @@ static void gizmo_calc_rect_view_scale(
asp[1] = dims[0] / dims[1];
}
float x_axis[3], y_axis[3];
- WM_gizmo_calc_matrix_final_no_offset(mpr, matrix_final_no_offset);
- mul_v3_mat3_m4v3(x_axis, matrix_final_no_offset, mpr->matrix_offset[0]);
- mul_v3_mat3_m4v3(y_axis, matrix_final_no_offset, mpr->matrix_offset[1]);
+ WM_gizmo_calc_matrix_final_no_offset(gz, matrix_final_no_offset);
+ mul_v3_mat3_m4v3(x_axis, matrix_final_no_offset, gz->matrix_offset[0]);
+ mul_v3_mat3_m4v3(y_axis, matrix_final_no_offset, gz->matrix_offset[1]);
mul_v2_v2(x_axis, asp);
mul_v2_v2(y_axis, asp);
@@ -91,18 +91,18 @@ static void gizmo_calc_rect_view_scale(
}
static void gizmo_calc_rect_view_margin(
- const wmGizmo *mpr, const float dims[2], float margin[2])
+ const wmGizmo *gz, const float dims[2], float margin[2])
{
float handle_size;
- if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
+ if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
handle_size = 0.15f;
}
else {
handle_size = GIZMO_RESIZER_SIZE;
}
- handle_size *= mpr->scale_final;
+ handle_size *= gz->scale_final;
float scale_xy[2];
- gizmo_calc_rect_view_scale(mpr, dims, scale_xy);
+ gizmo_calc_rect_view_scale(gz, dims, scale_xy);
margin[0] = ((handle_size * scale_xy[0]));
margin[1] = ((handle_size * scale_xy[1]));
}
@@ -136,12 +136,12 @@ static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[2], bool r_con
static void cage2d_draw_box_corners(
const rctf *r, const float margin[2], const float color[3])
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3fv(color);
- immBegin(GWN_PRIM_LINES, 16);
+ immBegin(GPU_PRIM_LINES, 16);
immVertex2f(pos, r->xmin, r->ymin + margin[1]);
immVertex2f(pos, r->xmin, r->ymin);
@@ -176,7 +176,7 @@ static void cage2d_draw_box_interaction(
/* 4 verts for translate, otherwise only 3 are used. */
float verts[4][2];
uint verts_len = 0;
- Gwn_PrimType prim_type = GWN_PRIM_NONE;
+ GPUPrimType prim_type = GPU_PRIM_NONE;
switch (highlighted) {
case ED_GIZMO_CAGE2D_PART_SCALE_MIN_X:
@@ -192,10 +192,10 @@ static void cage2d_draw_box_interaction(
ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymax);
ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymin);
verts_len += 2;
- prim_type = GWN_PRIM_TRI_FAN;
+ prim_type = GPU_PRIM_TRI_FAN;
}
else {
- prim_type = GWN_PRIM_LINE_STRIP;
+ prim_type = GPU_PRIM_LINE_STRIP;
}
break;
}
@@ -212,10 +212,10 @@ static void cage2d_draw_box_interaction(
ARRAY_SET_ITEMS(verts[2], r.xmin, r.ymax);
ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin);
verts_len += 2;
- prim_type = GWN_PRIM_TRI_FAN;
+ prim_type = GPU_PRIM_TRI_FAN;
}
else {
- prim_type = GWN_PRIM_LINE_STRIP;
+ prim_type = GPU_PRIM_LINE_STRIP;
}
break;
}
@@ -232,10 +232,10 @@ static void cage2d_draw_box_interaction(
ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymax);
ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymax);
verts_len += 2;
- prim_type = GWN_PRIM_TRI_FAN;
+ prim_type = GPU_PRIM_TRI_FAN;
}
else {
- prim_type = GWN_PRIM_LINE_STRIP;
+ prim_type = GPU_PRIM_LINE_STRIP;
}
break;
}
@@ -252,10 +252,10 @@ static void cage2d_draw_box_interaction(
ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymin);
ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin);
verts_len += 2;
- prim_type = GWN_PRIM_TRI_FAN;
+ prim_type = GPU_PRIM_TRI_FAN;
}
else {
- prim_type = GWN_PRIM_LINE_STRIP;
+ prim_type = GPU_PRIM_LINE_STRIP;
}
break;
}
@@ -272,10 +272,10 @@ static void cage2d_draw_box_interaction(
if (is_solid) {
ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin);
verts_len += 1;
- prim_type = GWN_PRIM_TRI_FAN;
+ prim_type = GPU_PRIM_TRI_FAN;
}
else {
- prim_type = GWN_PRIM_LINE_STRIP;
+ prim_type = GPU_PRIM_LINE_STRIP;
}
break;
}
@@ -292,10 +292,10 @@ static void cage2d_draw_box_interaction(
if (is_solid) {
ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymax);
verts_len += 1;
- prim_type = GWN_PRIM_TRI_FAN;
+ prim_type = GPU_PRIM_TRI_FAN;
}
else {
- prim_type = GWN_PRIM_LINE_STRIP;
+ prim_type = GPU_PRIM_LINE_STRIP;
}
break;
}
@@ -312,10 +312,10 @@ static void cage2d_draw_box_interaction(
if (is_solid) {
ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymin);
verts_len += 1;
- prim_type = GWN_PRIM_TRI_FAN;
+ prim_type = GPU_PRIM_TRI_FAN;
}
else {
- prim_type = GWN_PRIM_LINE_STRIP;
+ prim_type = GPU_PRIM_LINE_STRIP;
}
break;
}
@@ -332,10 +332,10 @@ static void cage2d_draw_box_interaction(
if (is_solid) {
ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymax);
verts_len += 1;
- prim_type = GWN_PRIM_TRI_FAN;
+ prim_type = GPU_PRIM_TRI_FAN;
}
else {
- prim_type = GWN_PRIM_LINE_STRIP;
+ prim_type = GPU_PRIM_LINE_STRIP;
}
break;
}
@@ -355,10 +355,10 @@ static void cage2d_draw_box_interaction(
ARRAY_SET_ITEMS(verts[3], r_rotate.xmax, r_rotate.ymin);
verts_len = 4;
if (is_solid) {
- prim_type = GWN_PRIM_TRI_FAN;
+ prim_type = GPU_PRIM_TRI_FAN;
}
else {
- prim_type = GWN_PRIM_LINE_STRIP;
+ prim_type = GPU_PRIM_LINE_STRIP;
}
break;
}
@@ -371,10 +371,10 @@ static void cage2d_draw_box_interaction(
ARRAY_SET_ITEMS(verts[3], margin[0] / 2, -margin[1] / 2);
verts_len = 4;
if (is_solid) {
- prim_type = GWN_PRIM_TRI_FAN;
+ prim_type = GPU_PRIM_TRI_FAN;
}
else {
- prim_type = GWN_PRIM_LINES;
+ prim_type = GPU_PRIM_LINES;
}
}
else {
@@ -385,12 +385,12 @@ static void cage2d_draw_box_interaction(
ARRAY_SET_ITEMS(verts[3], size[0], -size[1]);
verts_len = 4;
if (is_solid) {
- prim_type = GWN_PRIM_TRI_FAN;
+ prim_type = GPU_PRIM_TRI_FAN;
}
else {
/* unreachable */
BLI_assert(0);
- prim_type = GWN_PRIM_LINE_STRIP;
+ prim_type = GPU_PRIM_LINE_STRIP;
}
}
break;
@@ -398,20 +398,20 @@ static void cage2d_draw_box_interaction(
return;
}
- BLI_assert(prim_type != GWN_PRIM_NONE);
+ BLI_assert(prim_type != GPU_PRIM_NONE);
- Gwn_VertFormat *format = immVertexFormat();
+ GPUVertFormat *format = immVertexFormat();
struct {
uint pos, col;
} attr_id = {
- .pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT),
- .col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT),
+ .pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT),
+ .col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT),
};
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
{
if (is_solid) {
- BLI_assert(ELEM(prim_type, GWN_PRIM_TRI_FAN));
+ BLI_assert(ELEM(prim_type, GPU_PRIM_TRI_FAN));
immBegin(prim_type, verts_len);
immAttrib3f(attr_id.col, 0.0f, 0.0f, 0.0f);
for (uint i = 0; i < verts_len; i++) {
@@ -420,7 +420,7 @@ static void cage2d_draw_box_interaction(
immEnd();
}
else {
- BLI_assert(ELEM(prim_type, GWN_PRIM_LINE_STRIP, GWN_PRIM_LINES));
+ BLI_assert(ELEM(prim_type, GPU_PRIM_LINE_STRIP, GPU_PRIM_LINES));
GPU_line_width(line_width + 3.0f);
immBegin(prim_type, verts_len);
@@ -455,7 +455,7 @@ static void cage2d_draw_box_interaction(
static void imm_draw_point_aspect_2d(
uint pos, float x, float y, float rad_x, float rad_y, bool solid)
{
- immBegin(solid ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, 4);
+ immBegin(solid ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, 4);
immVertex2f(pos, x - rad_x, y - rad_y);
immVertex2f(pos, x - rad_x, y + rad_y);
immVertex2f(pos, x + rad_x, y + rad_y);
@@ -467,12 +467,12 @@ static void cage2d_draw_circle_wire(
const rctf *r, const float margin[2], const float color[3],
const int transform_flag, const int draw_options)
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3fv(color);
- immBegin(GWN_PRIM_LINE_LOOP, 4);
+ immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex2f(pos, r->xmin, r->ymin);
immVertex2f(pos, r->xmax, r->ymin);
immVertex2f(pos, r->xmax, r->ymax);
@@ -480,7 +480,7 @@ static void cage2d_draw_circle_wire(
immEnd();
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
- immBegin(GWN_PRIM_LINE_LOOP, 2);
+ immBegin(GPU_PRIM_LINE_LOOP, 2);
immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax);
immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1]);
immEnd();
@@ -491,7 +491,7 @@ static void cage2d_draw_circle_wire(
const float rad[2] = {margin[0] / 2, margin[1] / 2};
const float center[2] = {BLI_rctf_cent_x(r), BLI_rctf_cent_y(r)};
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, center[0] - rad[0], center[1] - rad[1]);
immVertex2f(pos, center[0] + rad[0], center[1] + rad[1]);
immVertex2f(pos, center[0] + rad[0], center[1] - rad[1]);
@@ -508,7 +508,7 @@ static void cage2d_draw_circle_handles(
const int transform_flag,
bool solid)
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
void (*circle_fn)(uint, float, float, float, float, int) =
(solid) ? imm_draw_circle_fill_aspect_2d : imm_draw_circle_wire_aspect_2d;
const int resolu = 12;
@@ -536,31 +536,31 @@ static void cage2d_draw_circle_handles(
/** \} */
static void gizmo_cage2d_draw_intern(
- wmGizmo *mpr, const bool select, const bool highlight, const int select_id)
+ wmGizmo *gz, const bool select, const bool highlight, const int select_id)
{
- // const bool use_clamp = (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0;
+ // const bool use_clamp = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0;
float dims[2];
- RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ RNA_float_get_array(gz->ptr, "dimensions", dims);
float matrix_final[4][4];
- const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
- const int draw_style = RNA_enum_get(mpr->ptr, "draw_style");
- const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ const int transform_flag = RNA_enum_get(gz->ptr, "transform");
+ const int draw_style = RNA_enum_get(gz->ptr, "draw_style");
+ const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
const float size_real[2] = {dims[0] / 2.0f, dims[1] / 2.0f};
- WM_gizmo_calc_matrix_final(mpr, matrix_final);
+ WM_gizmo_calc_matrix_final(gz, matrix_final);
- gpuPushMatrix();
- gpuMultMatrix(matrix_final);
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix_final);
float margin[2];
- gizmo_calc_rect_view_margin(mpr, dims, margin);
+ gizmo_calc_rect_view_margin(gz, dims, margin);
/* Handy for quick testing draw (if it's outside bounds). */
if (false) {
GPU_blend(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv((const float[4]){1, 1, 1, 0.5f});
float s = 0.5f;
@@ -588,18 +588,18 @@ static void gizmo_cage2d_draw_intern(
for (int i = 0; i < ARRAY_SIZE(scale_parts); i++) {
GPU_select_load_id(select_id | scale_parts[i]);
cage2d_draw_box_interaction(
- mpr->color, scale_parts[i], size, margin, mpr->line_width, true, draw_options);
+ gz->color, scale_parts[i], size, margin, gz->line_width, true, draw_options);
}
}
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
const int transform_part = ED_GIZMO_CAGE2D_PART_TRANSLATE;
GPU_select_load_id(select_id | transform_part);
cage2d_draw_box_interaction(
- mpr->color, transform_part, size, margin, mpr->line_width, true, draw_options);
+ gz->color, transform_part, size, margin, gz->line_width, true, draw_options);
}
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
cage2d_draw_box_interaction(
- mpr->color, ED_GIZMO_CAGE2D_PART_ROTATE, size_real, margin, mpr->line_width, true, draw_options);
+ gz->color, ED_GIZMO_CAGE2D_PART_ROTATE, size_real, margin, gz->line_width, true, draw_options);
}
}
else {
@@ -611,17 +611,17 @@ static void gizmo_cage2d_draw_intern(
};
if (draw_style == ED_GIZMO_CAGE2D_STYLE_BOX) {
/* corner gizmos */
- GPU_line_width(mpr->line_width + 3.0f);
+ GPU_line_width(gz->line_width + 3.0f);
cage2d_draw_box_corners(&r, margin, (const float[3]){0, 0, 0});
/* corner gizmos */
float color[4];
- gizmo_color_get(mpr, highlight, color);
- GPU_line_width(mpr->line_width);
+ gizmo_color_get(gz, highlight, color);
+ GPU_line_width(gz->line_width);
cage2d_draw_box_corners(&r, margin, color);
bool show = false;
- if (mpr->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) {
+ if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) {
/* Only show if we're drawing the center handle
* otherwise the entire rectangle is the hotspot. */
if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) {
@@ -634,24 +634,24 @@ static void gizmo_cage2d_draw_intern(
if (show) {
cage2d_draw_box_interaction(
- mpr->color, mpr->highlight_part, size_real, margin, mpr->line_width, false, draw_options);
+ gz->color, gz->highlight_part, size_real, margin, gz->line_width, false, draw_options);
}
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
cage2d_draw_box_interaction(
- mpr->color, ED_GIZMO_CAGE2D_PART_ROTATE, size_real, margin, mpr->line_width, false, draw_options);
+ gz->color, ED_GIZMO_CAGE2D_PART_ROTATE, size_real, margin, gz->line_width, false, draw_options);
}
}
else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
float color[4];
- gizmo_color_get(mpr, highlight, color);
+ gizmo_color_get(gz, highlight, color);
GPU_line_smooth(true);
GPU_blend(true);
- GPU_line_width(mpr->line_width + 3.0f);
+ GPU_line_width(gz->line_width + 3.0f);
cage2d_draw_circle_wire(&r, margin, (const float[3]){0, 0, 0}, transform_flag, draw_options);
- GPU_line_width(mpr->line_width);
+ GPU_line_width(gz->line_width);
cage2d_draw_circle_wire(&r, margin, color, transform_flag, draw_options);
@@ -668,28 +668,28 @@ static void gizmo_cage2d_draw_intern(
}
GPU_line_width(1.0);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
/**
* For when we want to draw 2d cage in 3d views.
*/
-static void gizmo_cage2d_draw_select(const bContext *UNUSED(C), wmGizmo *mpr, int select_id)
+static void gizmo_cage2d_draw_select(const bContext *UNUSED(C), wmGizmo *gz, int select_id)
{
- gizmo_cage2d_draw_intern(mpr, true, false, select_id);
+ gizmo_cage2d_draw_intern(gz, true, false, select_id);
}
-static void gizmo_cage2d_draw(const bContext *UNUSED(C), wmGizmo *mpr)
+static void gizmo_cage2d_draw(const bContext *UNUSED(C), wmGizmo *gz)
{
- const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
- gizmo_cage2d_draw_intern(mpr, false, is_highlight, -1);
+ const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
+ gizmo_cage2d_draw_intern(gz, false, is_highlight, -1);
}
-static int gizmo_cage2d_get_cursor(wmGizmo *mpr)
+static int gizmo_cage2d_get_cursor(wmGizmo *gz)
{
- int highlight_part = mpr->highlight_part;
+ int highlight_part = gz->highlight_part;
- if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
+ if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
return BC_NSEW_SCROLLCURSOR;
}
@@ -718,26 +718,26 @@ static int gizmo_cage2d_get_cursor(wmGizmo *mpr)
}
static int gizmo_cage2d_test_select(
- bContext *C, wmGizmo *mpr, const wmEvent *event)
+ bContext *C, wmGizmo *gz, const int mval[2])
{
float point_local[2];
float dims[2];
- RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ RNA_float_get_array(gz->ptr, "dimensions", dims);
const float size_real[2] = {dims[0] / 2.0f, dims[1] / 2.0f};
if (gizmo_window_project_2d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false)
+ C, gz, (const float[2]){UNPACK2(mval)}, 2, true, point_local) == false)
{
return -1;
}
float margin[2];
- gizmo_calc_rect_view_margin(mpr, dims, margin);
+ gizmo_calc_rect_view_margin(gz, dims, margin);
/* expand for hotspot */
const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2};
- const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
- const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ const int transform_flag = RNA_enum_get(gz->ptr, "transform");
+ const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
rctf r;
@@ -821,32 +821,32 @@ typedef struct RectTransformInteraction {
Dial *dial;
} RectTransformInteraction;
-static void gizmo_cage2d_setup(wmGizmo *mpr)
+static void gizmo_cage2d_setup(wmGizmo *gz)
{
- mpr->flag |= WM_GIZMO_DRAW_MODAL | WM_GIZMO_DRAW_NO_SCALE;
+ gz->flag |= WM_GIZMO_DRAW_MODAL | WM_GIZMO_DRAW_NO_SCALE;
}
static int gizmo_cage2d_invoke(
- bContext *C, wmGizmo *mpr, const wmEvent *event)
+ bContext *C, wmGizmo *gz, const wmEvent *event)
{
RectTransformInteraction *data = MEM_callocN(sizeof(RectTransformInteraction), "cage_interaction");
- copy_m4_m4(data->orig_matrix_offset, mpr->matrix_offset);
- WM_gizmo_calc_matrix_final_no_offset(mpr, data->orig_matrix_final_no_offset);
+ copy_m4_m4(data->orig_matrix_offset, gz->matrix_offset);
+ WM_gizmo_calc_matrix_final_no_offset(gz, data->orig_matrix_final_no_offset);
if (gizmo_window_project_2d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, data->orig_mouse) == 0)
+ C, gz, (const float[2]){UNPACK2(event->mval)}, 2, false, data->orig_mouse) == 0)
{
zero_v2(data->orig_mouse);
}
- mpr->interaction_data = data;
+ gz->interaction_data = data;
return OPERATOR_RUNNING_MODAL;
}
static int gizmo_cage2d_modal(
- bContext *C, wmGizmo *mpr, const wmEvent *event,
+ bContext *C, wmGizmo *gz, const wmEvent *event,
eWM_GizmoFlagTweak UNUSED(tweak_flag))
{
/* For transform logic to be managable we operate in -0.5..0.5 2D space,
@@ -856,40 +856,40 @@ static int gizmo_cage2d_modal(
* - The cursor offset are multiplied by 'dims'.
* - Matrix translation is also multiplied by 'dims'.
*/
- RectTransformInteraction *data = mpr->interaction_data;
+ RectTransformInteraction *data = gz->interaction_data;
float point_local[2];
float dims[2];
- RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ RNA_float_get_array(gz->ptr, "dimensions", dims);
{
float matrix_back[4][4];
- copy_m4_m4(matrix_back, mpr->matrix_offset);
- copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
+ copy_m4_m4(matrix_back, gz->matrix_offset);
+ copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
bool ok = gizmo_window_project_2d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, point_local);
- copy_m4_m4(mpr->matrix_offset, matrix_back);
+ C, gz, (const float[2]){UNPACK2(event->mval)}, 2, false, point_local);
+ copy_m4_m4(gz->matrix_offset, matrix_back);
if (!ok) {
return OPERATOR_RUNNING_MODAL;
}
}
- const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
- wmGizmoProperty *mpr_prop;
+ const int transform_flag = RNA_enum_get(gz->ptr, "transform");
+ wmGizmoProperty *gz_prop;
- mpr_prop = WM_gizmo_target_property_find(mpr, "matrix");
- if (mpr_prop->type != NULL) {
- WM_gizmo_target_property_value_get_array(mpr, mpr_prop, &mpr->matrix_offset[0][0]);
+ gz_prop = WM_gizmo_target_property_find(gz, "matrix");
+ if (gz_prop->type != NULL) {
+ WM_gizmo_target_property_value_get_array(gz, gz_prop, &gz->matrix_offset[0][0]);
}
- if (mpr->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) {
+ if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) {
/* do this to prevent clamping from changing size */
- copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
- mpr->matrix_offset[3][0] = data->orig_matrix_offset[3][0] + (point_local[0] - data->orig_mouse[0]);
- mpr->matrix_offset[3][1] = data->orig_matrix_offset[3][1] + (point_local[1] - data->orig_mouse[1]);
+ copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
+ gz->matrix_offset[3][0] = data->orig_matrix_offset[3][0] + (point_local[0] - data->orig_mouse[0]);
+ gz->matrix_offset[3][1] = data->orig_matrix_offset[3][1] + (point_local[1] - data->orig_mouse[1]);
}
- else if (mpr->highlight_part == ED_GIZMO_CAGE2D_PART_ROTATE) {
+ else if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_ROTATE) {
#define MUL_V2_V3_M4_FINAL(test_co, mouse_co) \
mul_v3_m4v3(test_co, data->orig_matrix_final_no_offset, ((const float[3]){UNPACK2(mouse_co), 0.0}))
@@ -915,28 +915,28 @@ static int gizmo_cage2d_modal(
copy_v3_v3(pivot, data->orig_matrix_offset[3]);
- invert_m4_m4(matrix_space_inv, mpr->matrix_space);
+ invert_m4_m4(matrix_space_inv, gz->matrix_space);
unit_m4(matrix_rotate);
mul_m4_m4m4(matrix_rotate, matrix_rotate, matrix_space_inv);
rotate_m4(matrix_rotate, 'Z', -angle);
- mul_m4_m4m4(matrix_rotate, matrix_rotate, mpr->matrix_space);
+ mul_m4_m4m4(matrix_rotate, matrix_rotate, gz->matrix_space);
zero_v3(matrix_rotate[3]);
transform_pivot_set_m4(matrix_rotate, pivot);
- mul_m4_m4m4(mpr->matrix_offset, matrix_rotate, data->orig_matrix_offset);
+ mul_m4_m4m4(gz->matrix_offset, matrix_rotate, data->orig_matrix_offset);
#undef MUL_V2_V3_M4_FINAL
}
else {
/* scale */
- copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
+ copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
float pivot[2];
bool constrain_axis[2] = {false};
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
- gizmo_rect_pivot_from_scale_part(mpr->highlight_part, pivot, constrain_axis);
+ gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis);
}
else {
zero_v2(pivot);
@@ -991,11 +991,11 @@ static int gizmo_cage2d_modal(
mul_v3_fl(matrix_scale[1], scale[1]);
transform_pivot_set_m4(matrix_scale, (const float[3]){pivot[0] * dims[0], pivot[1] * dims[1], 0.0f});
- mul_m4_m4m4(mpr->matrix_offset, data->orig_matrix_offset, matrix_scale);
+ mul_m4_m4m4(gz->matrix_offset, data->orig_matrix_offset, matrix_scale);
}
- if (mpr_prop->type != NULL) {
- WM_gizmo_target_property_value_set_array(C, mpr, mpr_prop, &mpr->matrix_offset[0][0]);
+ if (gz_prop->type != NULL) {
+ WM_gizmo_target_property_value_set_array(C, gz, gz_prop, &gz->matrix_offset[0][0]);
}
/* tag the region for redraw */
@@ -1005,11 +1005,11 @@ static int gizmo_cage2d_modal(
return OPERATOR_RUNNING_MODAL;
}
-static void gizmo_cage2d_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop)
+static void gizmo_cage2d_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop)
{
- if (STREQ(mpr_prop->type->idname, "matrix")) {
- if (WM_gizmo_target_property_array_length(mpr, mpr_prop) == 16) {
- WM_gizmo_target_property_value_get_array(mpr, mpr_prop, &mpr->matrix_offset[0][0]);
+ if (STREQ(gz_prop->type->idname, "matrix")) {
+ if (WM_gizmo_target_property_array_length(gz, gz_prop) == 16) {
+ WM_gizmo_target_property_value_get_array(gz, gz_prop, &gz->matrix_offset[0][0]);
}
else {
BLI_assert(0);
@@ -1020,24 +1020,24 @@ static void gizmo_cage2d_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop
}
}
-static void gizmo_cage2d_exit(bContext *C, wmGizmo *mpr, const bool cancel)
+static void gizmo_cage2d_exit(bContext *C, wmGizmo *gz, const bool cancel)
{
- RectTransformInteraction *data = mpr->interaction_data;
+ RectTransformInteraction *data = gz->interaction_data;
MEM_SAFE_FREE(data->dial);
if (!cancel)
return;
- wmGizmoProperty *mpr_prop;
+ wmGizmoProperty *gz_prop;
/* reset properties */
- mpr_prop = WM_gizmo_target_property_find(mpr, "matrix");
- if (mpr_prop->type != NULL) {
- WM_gizmo_target_property_value_set_array(C, mpr, mpr_prop, &data->orig_matrix_offset[0][0]);
+ gz_prop = WM_gizmo_target_property_find(gz, "matrix");
+ if (gz_prop->type != NULL) {
+ WM_gizmo_target_property_value_set_array(C, gz, gz_prop, &data->orig_matrix_offset[0][0]);
}
- copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
+ copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
}
@@ -1046,23 +1046,23 @@ static void gizmo_cage2d_exit(bContext *C, wmGizmo *mpr, const bool cancel)
*
* \{ */
-static void GIZMO_WT_cage_2d(wmGizmoType *wt)
+static void GIZMO_GT_cage_2d(wmGizmoType *gzt)
{
/* identifiers */
- wt->idname = "GIZMO_WT_cage_2d";
+ gzt->idname = "GIZMO_GT_cage_2d";
/* api callbacks */
- wt->draw = gizmo_cage2d_draw;
- wt->draw_select = gizmo_cage2d_draw_select;
- wt->test_select = gizmo_cage2d_test_select;
- wt->setup = gizmo_cage2d_setup;
- wt->invoke = gizmo_cage2d_invoke;
- wt->property_update = gizmo_cage2d_property_update;
- wt->modal = gizmo_cage2d_modal;
- wt->exit = gizmo_cage2d_exit;
- wt->cursor_get = gizmo_cage2d_get_cursor;
-
- wt->struct_size = sizeof(wmGizmo);
+ gzt->draw = gizmo_cage2d_draw;
+ gzt->draw_select = gizmo_cage2d_draw_select;
+ gzt->test_select = gizmo_cage2d_test_select;
+ gzt->setup = gizmo_cage2d_setup;
+ gzt->invoke = gizmo_cage2d_invoke;
+ gzt->property_update = gizmo_cage2d_property_update;
+ gzt->modal = gizmo_cage2d_modal;
+ gzt->exit = gizmo_cage2d_exit;
+ gzt->cursor_get = gizmo_cage2d_get_cursor;
+
+ gzt->struct_size = sizeof(wmGizmo);
/* rna */
static EnumPropertyItem rna_enum_draw_style[] = {
@@ -1082,19 +1082,19 @@ static void GIZMO_WT_cage_2d(wmGizmoType *wt)
{0, NULL, 0, NULL, NULL}
};
static float unit_v2[2] = {1.0f, 1.0f};
- RNA_def_float_vector(wt->srna, "dimensions", 2, unit_v2, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX);
- RNA_def_enum_flag(wt->srna, "transform", rna_enum_transform, 0, "Transform Options", "");
- RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_CAGE2D_STYLE_CIRCLE, "Draw Style", "");
+ RNA_def_float_vector(gzt->srna, "dimensions", 2, unit_v2, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX);
+ RNA_def_enum_flag(gzt->srna, "transform", rna_enum_transform, 0, "Transform Options", "");
+ RNA_def_enum(gzt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_CAGE2D_STYLE_CIRCLE, "Draw Style", "");
RNA_def_enum_flag(
- wt->srna, "draw_options", rna_enum_draw_options,
+ gzt->srna, "draw_options", rna_enum_draw_options,
ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE, "Draw Options", "");
- WM_gizmotype_target_property_def(wt, "matrix", PROP_FLOAT, 16);
+ WM_gizmotype_target_property_def(gzt, "matrix", PROP_FLOAT, 16);
}
void ED_gizmotypes_cage_2d(void)
{
- WM_gizmotype_append(GIZMO_WT_cage_2d);
+ WM_gizmotype_append(GIZMO_GT_cage_2d);
}
/** \} */
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
index e266514855b..0f1d309c927 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
@@ -67,7 +67,7 @@
#define GIZMO_MARGIN_OFFSET_SCALE 1.5f
static void gizmo_calc_matrix_final_no_offset(
- const wmGizmo *mpr, float orig_matrix_final_no_offset[4][4], bool use_space)
+ const wmGizmo *gz, float orig_matrix_final_no_offset[4][4], bool use_space)
{
float mat_identity[4][4];
struct WM_GizmoMatrixParams params = {NULL};
@@ -76,11 +76,11 @@ static void gizmo_calc_matrix_final_no_offset(
params.matrix_basis = mat_identity;
}
params.matrix_offset = mat_identity;
- WM_gizmo_calc_matrix_final_params(mpr, &params, orig_matrix_final_no_offset);
+ WM_gizmo_calc_matrix_final_params(gz, &params, orig_matrix_final_no_offset);
}
static void gizmo_calc_rect_view_scale(
- const wmGizmo *mpr, const float dims[3], float scale[3])
+ const wmGizmo *gz, const float dims[3], float scale[3])
{
UNUSED_VARS(dims);
@@ -88,10 +88,10 @@ static void gizmo_calc_rect_view_scale(
float matrix_final_no_offset[4][4];
float x_axis[3], y_axis[3], z_axis[3];
- gizmo_calc_matrix_final_no_offset(mpr, matrix_final_no_offset, false);
- mul_v3_mat3_m4v3(x_axis, matrix_final_no_offset, mpr->matrix_offset[0]);
- mul_v3_mat3_m4v3(y_axis, matrix_final_no_offset, mpr->matrix_offset[1]);
- mul_v3_mat3_m4v3(z_axis, matrix_final_no_offset, mpr->matrix_offset[2]);
+ gizmo_calc_matrix_final_no_offset(gz, matrix_final_no_offset, false);
+ mul_v3_mat3_m4v3(x_axis, matrix_final_no_offset, gz->matrix_offset[0]);
+ mul_v3_mat3_m4v3(y_axis, matrix_final_no_offset, gz->matrix_offset[1]);
+ mul_v3_mat3_m4v3(z_axis, matrix_final_no_offset, gz->matrix_offset[2]);
scale[0] = 1.0f / len_v3(x_axis);
scale[1] = 1.0f / len_v3(y_axis);
@@ -99,20 +99,20 @@ static void gizmo_calc_rect_view_scale(
}
static void gizmo_calc_rect_view_margin(
- const wmGizmo *mpr, const float dims[3], float margin[3])
+ const wmGizmo *gz, const float dims[3], float margin[3])
{
float handle_size;
- if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
+ if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
handle_size = 0.15f;
}
else {
handle_size = GIZMO_RESIZER_SIZE;
}
// XXX, the scale isn't taking offset into account, we need to calculate scale per handle!
- // handle_size *= mpr->scale_final;
+ // handle_size *= gz->scale_final;
float scale_xyz[3];
- gizmo_calc_rect_view_scale(mpr, dims, scale_xyz);
+ gizmo_calc_rect_view_scale(gz, dims, scale_xyz);
margin[0] = ((handle_size * scale_xyz[0]));
margin[1] = ((handle_size * scale_xyz[1]));
margin[2] = ((handle_size * scale_xyz[2]));
@@ -150,7 +150,7 @@ static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[3], bool r_con
static void cage3d_draw_box_corners(
const float r[3], const float margin[3], const float color[3])
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
UNUSED_VARS(margin);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -185,7 +185,7 @@ static void cage3d_draw_box_interaction(
const float rad[3] = {margin[0] / 3, margin[1] / 3, margin[2] / 3};
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor3fv(color);
imm_draw_cube_fill_3d(pos, co, rad);
@@ -217,7 +217,7 @@ static void cage3d_draw_circle_wire(
const float r[3], const float margin[3], const float color[3],
const int transform_flag, const int draw_options)
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor3fv(color);
@@ -230,7 +230,7 @@ static void cage3d_draw_circle_wire(
const float rad[2] = {margin[0] / 2, margin[1] / 2};
const float center[2] = {0.0f, 0.0f};
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, center[0] - rad[0], center[1] - rad[1]);
immVertex2f(pos, center[0] + rad[0], center[1] + rad[1]);
immVertex2f(pos, center[0] + rad[0], center[1] - rad[1]);
@@ -251,7 +251,7 @@ static void cage3d_draw_circle_handles(
const float r[3], const float margin[3], const float color[3],
bool solid, float scale)
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
const float rad[3] = {margin[0] / 3, margin[1] / 3, margin[2] / 3};
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -281,31 +281,31 @@ static void cage3d_draw_circle_handles(
static void gizmo_cage3d_draw_intern(
RegionView3D *rv3d,
- wmGizmo *mpr, const bool select, const bool highlight, const int select_id)
+ wmGizmo *gz, const bool select, const bool highlight, const int select_id)
{
- // const bool use_clamp = (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0;
+ // const bool use_clamp = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0;
float dims[3];
- RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ RNA_float_get_array(gz->ptr, "dimensions", dims);
float matrix_final[4][4];
- const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
- const int draw_style = RNA_enum_get(mpr->ptr, "draw_style");
- const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ const int transform_flag = RNA_enum_get(gz->ptr, "transform");
+ const int draw_style = RNA_enum_get(gz->ptr, "draw_style");
+ const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
const float size_real[3] = {dims[0] / 2.0f, dims[1] / 2.0f, dims[2] / 2.0f};
- WM_gizmo_calc_matrix_final(mpr, matrix_final);
+ WM_gizmo_calc_matrix_final(gz, matrix_final);
- gpuPushMatrix();
- gpuMultMatrix(matrix_final);
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix_final);
float margin[3];
- gizmo_calc_rect_view_margin(mpr, dims, margin);
+ gizmo_calc_rect_view_margin(gz, dims, margin);
/* Handy for quick testing draw (if it's outside bounds). */
if (false) {
GPU_blend(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv((const float[4]){1, 1, 1, 0.5f});
float s = 0.5f;
@@ -338,14 +338,14 @@ static void gizmo_cage3d_draw_intern(
}
GPU_select_load_id(select_id | i);
cage3d_draw_box_interaction(
- mpr->color, i, size, margin);
+ gz->color, i, size, margin);
}
}
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
const int transform_part = ED_GIZMO_CAGE3D_PART_TRANSLATE;
GPU_select_load_id(select_id | transform_part);
cage3d_draw_box_interaction(
- mpr->color, transform_part, size, margin);
+ gz->color, transform_part, size, margin);
}
}
else {
@@ -359,17 +359,17 @@ static void gizmo_cage3d_draw_intern(
#endif
if (draw_style == ED_GIZMO_CAGE2D_STYLE_BOX) {
/* corner gizmos */
- GPU_line_width(mpr->line_width + 3.0f);
+ GPU_line_width(gz->line_width + 3.0f);
cage3d_draw_box_corners(size_real, margin, (const float[3]){0, 0, 0});
/* corner gizmos */
float color[4];
- gizmo_color_get(mpr, highlight, color);
- GPU_line_width(mpr->line_width);
+ gizmo_color_get(gz, highlight, color);
+ GPU_line_width(gz->line_width);
cage3d_draw_box_corners(size_real, margin, color);
bool show = false;
- if (mpr->highlight_part == ED_GIZMO_CAGE3D_PART_TRANSLATE) {
+ if (gz->highlight_part == ED_GIZMO_CAGE3D_PART_TRANSLATE) {
/* Only show if we're drawing the center handle
* otherwise the entire rectangle is the hotspot. */
if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) {
@@ -382,20 +382,20 @@ static void gizmo_cage3d_draw_intern(
if (show) {
cage3d_draw_box_interaction(
- mpr->color, mpr->highlight_part, size_real, margin);
+ gz->color, gz->highlight_part, size_real, margin);
}
}
else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
float color[4];
- gizmo_color_get(mpr, highlight, color);
+ gizmo_color_get(gz, highlight, color);
GPU_line_smooth(true);
GPU_polygon_smooth(true);
GPU_blend(true);
- GPU_line_width(mpr->line_width + 3.0f);
+ GPU_line_width(gz->line_width + 3.0f);
cage3d_draw_circle_wire(size_real, margin, (const float[3]){0, 0, 0}, transform_flag, draw_options);
- GPU_line_width(mpr->line_width);
+ GPU_line_width(gz->line_width);
cage3d_draw_circle_wire(size_real, margin, color, transform_flag, draw_options);
/* corner gizmos */
@@ -412,30 +412,30 @@ static void gizmo_cage3d_draw_intern(
}
GPU_line_width(1.0);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
/**
* For when we want to draw 3d cage in 3d views.
*/
-static void gizmo_cage3d_draw_select(const bContext *C, wmGizmo *mpr, int select_id)
+static void gizmo_cage3d_draw_select(const bContext *C, wmGizmo *gz, int select_id)
{
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = ar->regiondata;
- gizmo_cage3d_draw_intern(rv3d, mpr, true, false, select_id);
+ gizmo_cage3d_draw_intern(rv3d, gz, true, false, select_id);
}
-static void gizmo_cage3d_draw(const bContext *C, wmGizmo *mpr)
+static void gizmo_cage3d_draw(const bContext *C, wmGizmo *gz)
{
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = ar->regiondata;
- const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
- gizmo_cage3d_draw_intern(rv3d, mpr, false, is_highlight, -1);
+ const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
+ gizmo_cage3d_draw_intern(rv3d, gz, false, is_highlight, -1);
}
-static int gizmo_cage3d_get_cursor(wmGizmo *mpr)
+static int gizmo_cage3d_get_cursor(wmGizmo *gz)
{
- if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
+ if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
return BC_NSEW_SCROLLCURSOR;
}
@@ -448,33 +448,33 @@ typedef struct RectTransformInteraction {
float orig_matrix_final_no_offset[4][4];
} RectTransformInteraction;
-static void gizmo_cage3d_setup(wmGizmo *mpr)
+static void gizmo_cage3d_setup(wmGizmo *gz)
{
- mpr->flag |= /* WM_GIZMO_DRAW_MODAL | */ /* TODO */
+ gz->flag |= /* WM_GIZMO_DRAW_MODAL | */ /* TODO */
WM_GIZMO_DRAW_NO_SCALE;
}
static int gizmo_cage3d_invoke(
- bContext *C, wmGizmo *mpr, const wmEvent *event)
+ bContext *C, wmGizmo *gz, const wmEvent *event)
{
RectTransformInteraction *data = MEM_callocN(sizeof(RectTransformInteraction), "cage_interaction");
- copy_m4_m4(data->orig_matrix_offset, mpr->matrix_offset);
- gizmo_calc_matrix_final_no_offset(mpr, data->orig_matrix_final_no_offset, true);
+ copy_m4_m4(data->orig_matrix_offset, gz->matrix_offset);
+ gizmo_calc_matrix_final_no_offset(gz, data->orig_matrix_final_no_offset, true);
if (gizmo_window_project_3d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, false, data->orig_mouse) == 0)
+ C, gz, (const float[2]){UNPACK2(event->mval)}, false, data->orig_mouse) == 0)
{
zero_v3(data->orig_mouse);
}
- mpr->interaction_data = data;
+ gz->interaction_data = data;
return OPERATOR_RUNNING_MODAL;
}
static int gizmo_cage3d_modal(
- bContext *C, wmGizmo *mpr, const wmEvent *event,
+ bContext *C, wmGizmo *gz, const wmEvent *event,
eWM_GizmoFlagTweak UNUSED(tweak_flag))
{
/* For transform logic to be managable we operate in -0.5..0.5 2D space,
@@ -484,51 +484,51 @@ static int gizmo_cage3d_modal(
* - The cursor offset are multiplied by 'dims'.
* - Matrix translation is also multiplied by 'dims'.
*/
- RectTransformInteraction *data = mpr->interaction_data;
+ RectTransformInteraction *data = gz->interaction_data;
float point_local[3];
float dims[3];
- RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ RNA_float_get_array(gz->ptr, "dimensions", dims);
{
float matrix_back[4][4];
- copy_m4_m4(matrix_back, mpr->matrix_offset);
- copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
+ copy_m4_m4(matrix_back, gz->matrix_offset);
+ copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
bool ok = gizmo_window_project_3d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, false, point_local);
- copy_m4_m4(mpr->matrix_offset, matrix_back);
+ C, gz, (const float[2]){UNPACK2(event->mval)}, false, point_local);
+ copy_m4_m4(gz->matrix_offset, matrix_back);
if (!ok) {
return OPERATOR_RUNNING_MODAL;
}
}
- const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
- wmGizmoProperty *mpr_prop;
+ const int transform_flag = RNA_enum_get(gz->ptr, "transform");
+ wmGizmoProperty *gz_prop;
- mpr_prop = WM_gizmo_target_property_find(mpr, "matrix");
- if (mpr_prop->type != NULL) {
- WM_gizmo_target_property_value_get_array(mpr, mpr_prop, &mpr->matrix_offset[0][0]);
+ gz_prop = WM_gizmo_target_property_find(gz, "matrix");
+ if (gz_prop->type != NULL) {
+ WM_gizmo_target_property_value_get_array(gz, gz_prop, &gz->matrix_offset[0][0]);
}
- if (mpr->highlight_part == ED_GIZMO_CAGE3D_PART_TRANSLATE) {
+ if (gz->highlight_part == ED_GIZMO_CAGE3D_PART_TRANSLATE) {
/* do this to prevent clamping from changing size */
- copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
- mpr->matrix_offset[3][0] = data->orig_matrix_offset[3][0] + (point_local[0] - data->orig_mouse[0]);
- mpr->matrix_offset[3][1] = data->orig_matrix_offset[3][1] + (point_local[1] - data->orig_mouse[1]);
- mpr->matrix_offset[3][2] = data->orig_matrix_offset[3][2] + (point_local[2] - data->orig_mouse[2]);
+ copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
+ gz->matrix_offset[3][0] = data->orig_matrix_offset[3][0] + (point_local[0] - data->orig_mouse[0]);
+ gz->matrix_offset[3][1] = data->orig_matrix_offset[3][1] + (point_local[1] - data->orig_mouse[1]);
+ gz->matrix_offset[3][2] = data->orig_matrix_offset[3][2] + (point_local[2] - data->orig_mouse[2]);
}
- else if (mpr->highlight_part == ED_GIZMO_CAGE3D_PART_ROTATE) {
+ else if (gz->highlight_part == ED_GIZMO_CAGE3D_PART_ROTATE) {
/* TODO (if needed) */
}
else {
/* scale */
- copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
+ copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
float pivot[3];
bool constrain_axis[3] = {false};
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
- gizmo_rect_pivot_from_scale_part(mpr->highlight_part, pivot, constrain_axis);
+ gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis);
}
else {
zero_v3(pivot);
@@ -587,11 +587,11 @@ static int gizmo_cage3d_modal(
transform_pivot_set_m4(
matrix_scale,
(const float[3]){pivot[0] * dims[0], pivot[1] * dims[1], pivot[2] * dims[2]});
- mul_m4_m4m4(mpr->matrix_offset, data->orig_matrix_offset, matrix_scale);
+ mul_m4_m4m4(gz->matrix_offset, data->orig_matrix_offset, matrix_scale);
}
- if (mpr_prop->type != NULL) {
- WM_gizmo_target_property_value_set_array(C, mpr, mpr_prop, &mpr->matrix_offset[0][0]);
+ if (gz_prop->type != NULL) {
+ WM_gizmo_target_property_value_set_array(C, gz, gz_prop, &gz->matrix_offset[0][0]);
}
/* tag the region for redraw */
@@ -601,11 +601,11 @@ static int gizmo_cage3d_modal(
return OPERATOR_RUNNING_MODAL;
}
-static void gizmo_cage3d_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop)
+static void gizmo_cage3d_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop)
{
- if (STREQ(mpr_prop->type->idname, "matrix")) {
- if (WM_gizmo_target_property_array_length(mpr, mpr_prop) == 16) {
- WM_gizmo_target_property_value_get_array(mpr, mpr_prop, &mpr->matrix_offset[0][0]);
+ if (STREQ(gz_prop->type->idname, "matrix")) {
+ if (WM_gizmo_target_property_array_length(gz, gz_prop) == 16) {
+ WM_gizmo_target_property_value_get_array(gz, gz_prop, &gz->matrix_offset[0][0]);
}
else {
BLI_assert(0);
@@ -616,22 +616,22 @@ static void gizmo_cage3d_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop
}
}
-static void gizmo_cage3d_exit(bContext *C, wmGizmo *mpr, const bool cancel)
+static void gizmo_cage3d_exit(bContext *C, wmGizmo *gz, const bool cancel)
{
- RectTransformInteraction *data = mpr->interaction_data;
+ RectTransformInteraction *data = gz->interaction_data;
if (!cancel)
return;
- wmGizmoProperty *mpr_prop;
+ wmGizmoProperty *gz_prop;
/* reset properties */
- mpr_prop = WM_gizmo_target_property_find(mpr, "matrix");
- if (mpr_prop->type != NULL) {
- WM_gizmo_target_property_value_set_array(C, mpr, mpr_prop, &data->orig_matrix_offset[0][0]);
+ gz_prop = WM_gizmo_target_property_find(gz, "matrix");
+ if (gz_prop->type != NULL) {
+ WM_gizmo_target_property_value_set_array(C, gz, gz_prop, &data->orig_matrix_offset[0][0]);
}
- copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
+ copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
}
@@ -640,22 +640,22 @@ static void gizmo_cage3d_exit(bContext *C, wmGizmo *mpr, const bool cancel)
*
* \{ */
-static void GIZMO_WT_cage_3d(wmGizmoType *wt)
+static void GIZMO_GT_cage_3d(wmGizmoType *gzt)
{
/* identifiers */
- wt->idname = "GIZMO_WT_cage_3d";
+ gzt->idname = "GIZMO_GT_cage_3d";
/* api callbacks */
- wt->draw = gizmo_cage3d_draw;
- wt->draw_select = gizmo_cage3d_draw_select;
- wt->setup = gizmo_cage3d_setup;
- wt->invoke = gizmo_cage3d_invoke;
- wt->property_update = gizmo_cage3d_property_update;
- wt->modal = gizmo_cage3d_modal;
- wt->exit = gizmo_cage3d_exit;
- wt->cursor_get = gizmo_cage3d_get_cursor;
+ gzt->draw = gizmo_cage3d_draw;
+ gzt->draw_select = gizmo_cage3d_draw_select;
+ gzt->setup = gizmo_cage3d_setup;
+ gzt->invoke = gizmo_cage3d_invoke;
+ gzt->property_update = gizmo_cage3d_property_update;
+ gzt->modal = gizmo_cage3d_modal;
+ gzt->exit = gizmo_cage3d_exit;
+ gzt->cursor_get = gizmo_cage3d_get_cursor;
- wt->struct_size = sizeof(wmGizmo);
+ gzt->struct_size = sizeof(wmGizmo);
/* rna */
static EnumPropertyItem rna_enum_draw_style[] = {
@@ -674,19 +674,19 @@ static void GIZMO_WT_cage_3d(wmGizmoType *wt)
{0, NULL, 0, NULL, NULL}
};
static float unit_v3[3] = {1.0f, 1.0f, 1.0f};
- RNA_def_float_vector(wt->srna, "dimensions", 3, unit_v3, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX);
- RNA_def_enum_flag(wt->srna, "transform", rna_enum_transform, 0, "Transform Options", "");
- RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_CAGE2D_STYLE_CIRCLE, "Draw Style", "");
+ RNA_def_float_vector(gzt->srna, "dimensions", 3, unit_v3, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX);
+ RNA_def_enum_flag(gzt->srna, "transform", rna_enum_transform, 0, "Transform Options", "");
+ RNA_def_enum(gzt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_CAGE2D_STYLE_CIRCLE, "Draw Style", "");
RNA_def_enum_flag(
- wt->srna, "draw_options", rna_enum_draw_options,
+ gzt->srna, "draw_options", rna_enum_draw_options,
ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE, "Draw Options", "");
- WM_gizmotype_target_property_def(wt, "matrix", PROP_FLOAT, 16);
+ WM_gizmotype_target_property_def(gzt, "matrix", PROP_FLOAT, 16);
}
void ED_gizmotypes_cage_3d(void)
{
- WM_gizmotype_append(GIZMO_WT_cage_3d);
+ WM_gizmotype_append(GIZMO_GT_cage_3d);
}
/** \} */
diff --git a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
index b93b87b1efa..8e04703c14e 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
@@ -71,7 +71,7 @@
// #define USE_GIZMO_CUSTOM_DIAL
static int gizmo_dial_modal(
- bContext *C, wmGizmo *mpr, const wmEvent *event,
+ bContext *C, wmGizmo *gz, const wmEvent *event,
eWM_GizmoFlagTweak tweak_flag);
typedef struct DialInteraction {
@@ -101,33 +101,33 @@ typedef struct DialInteraction {
/**
* We can't use this for the #wmGizmoType.matrix_basis_get callback, it conflicts with depth picking.
*/
-static void dial_calc_matrix(const wmGizmo *mpr, float mat[4][4])
+static void dial_calc_matrix(const wmGizmo *gz, float mat[4][4])
{
float rot[3][3];
const float up[3] = {0.0f, 0.0f, 1.0f};
- rotation_between_vecs_to_mat3(rot, up, mpr->matrix_basis[2]);
+ rotation_between_vecs_to_mat3(rot, up, gz->matrix_basis[2]);
copy_m4_m3(mat, rot);
- copy_v3_v3(mat[3], mpr->matrix_basis[3]);
+ copy_v3_v3(mat[3], gz->matrix_basis[3]);
}
/* -------------------------------------------------------------------- */
static void dial_geom_draw(
- const wmGizmo *mpr, const float color[4], const bool select,
+ const wmGizmo *gz, const float color[4], const bool select,
float axis_modal_mat[4][4], float clip_plane[4])
{
#ifdef USE_GIZMO_CUSTOM_DIAL
UNUSED_VARS(dial, col, axis_modal_mat, clip_plane);
wm_gizmo_geometryinfo_draw(&wm_gizmo_geom_data_dial, select);
#else
- const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
const bool filled = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_FILL) != 0;
- GPU_line_width(mpr->line_width);
+ GPU_line_width(gz->line_width);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (clip_plane) {
immBindBuiltinProgram(GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR);
@@ -161,32 +161,32 @@ static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[
{
GPU_line_width(1.0f);
- gpuPushMatrix();
- gpuRotate3f(RAD2DEGF(angle), 0.0f, 0.0f, -1.0f);
+ GPU_matrix_push();
+ GPU_matrix_rotate_3f(RAD2DEGF(angle), 0.0f, 0.0f, -1.0f);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(color);
- immBegin(GWN_PRIM_LINE_STRIP, 2);
+ immBegin(GPU_PRIM_LINE_STRIP, 2);
immVertex3f(pos, 0.0f, 0.0f, 0.0f);
immVertex3fv(pos, co_outer);
immEnd();
immUnbindProgram();
- gpuPopMatrix();
+ GPU_matrix_pop();
}
static void dial_ghostarc_draw(
- const wmGizmo *mpr, const float angle_ofs, const float angle_delta, const float color[4])
+ const wmGizmo *gz, const float angle_ofs, const float angle_delta, const float color[4])
{
- const float width_inner = DIAL_WIDTH - mpr->line_width * 0.5f / U.gizmo_size;
+ const float width_inner = DIAL_WIDTH - gz->line_width * 0.5f / U.gizmo_size;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(color);
imm_draw_disk_partial_fill_2d(
@@ -196,24 +196,24 @@ static void dial_ghostarc_draw(
static void dial_ghostarc_get_angles(
struct Depsgraph *depsgraph,
- const wmGizmo *mpr,
+ const wmGizmo *gz,
const wmEvent *event,
const ARegion *ar, const View3D *v3d,
float mat[4][4], const float co_outer[3],
float *r_start, float *r_delta)
{
- DialInteraction *inter = mpr->interaction_data;
+ DialInteraction *inter = gz->interaction_data;
const RegionView3D *rv3d = ar->regiondata;
const float mval[2] = {event->x - ar->winrct.xmin, event->y - ar->winrct.ymin};
/* we might need to invert the direction of the angles */
float view_vec[3], axis_vec[3];
- ED_view3d_global_to_vector(rv3d, mpr->matrix_basis[3], view_vec);
- normalize_v3_v3(axis_vec, mpr->matrix_basis[2]);
+ ED_view3d_global_to_vector(rv3d, gz->matrix_basis[3], view_vec);
+ normalize_v3_v3(axis_vec, gz->matrix_basis[2]);
float proj_outer_rel[3];
mul_v3_project_m4_v3(proj_outer_rel, mat, co_outer);
- sub_v3_v3(proj_outer_rel, mpr->matrix_basis[3]);
+ sub_v3_v3(proj_outer_rel, gz->matrix_basis[3]);
float proj_mval_new_rel[3];
float proj_mval_init_rel[3];
@@ -221,7 +221,7 @@ static void dial_ghostarc_get_angles(
float ray_co[3], ray_no[3];
float ray_lambda;
- plane_from_point_normal_v3(dial_plane, mpr->matrix_basis[3], axis_vec);
+ plane_from_point_normal_v3(dial_plane, gz->matrix_basis[3], axis_vec);
if (!ED_view3d_win_to_ray(depsgraph, ar, v3d, inter->init_mval, ray_co, ray_no, false) ||
!isect_ray_plane_v3(ray_co, ray_no, dial_plane, &ray_lambda, false))
@@ -229,7 +229,7 @@ static void dial_ghostarc_get_angles(
goto fail;
}
madd_v3_v3v3fl(proj_mval_init_rel, ray_co, ray_no, ray_lambda);
- sub_v3_v3(proj_mval_init_rel, mpr->matrix_basis[3]);
+ sub_v3_v3(proj_mval_init_rel, gz->matrix_basis[3]);
if (!ED_view3d_win_to_ray(depsgraph, ar, v3d, mval, ray_co, ray_no, false) ||
!isect_ray_plane_v3(ray_co, ray_no, dial_plane, &ray_lambda, false))
@@ -237,14 +237,14 @@ static void dial_ghostarc_get_angles(
goto fail;
}
madd_v3_v3v3fl(proj_mval_new_rel, ray_co, ray_no, ray_lambda);
- sub_v3_v3(proj_mval_new_rel, mpr->matrix_basis[3]);
+ sub_v3_v3(proj_mval_new_rel, gz->matrix_basis[3]);
- const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
/* Start direction from mouse or set by user */
const float *proj_init_rel =
(draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y) ?
- mpr->matrix_basis[1] : proj_mval_init_rel;
+ gz->matrix_basis[1] : proj_mval_init_rel;
/* return angles */
const float start = angle_wrap_rad(angle_signed_on_axis_v3v3_v3(proj_outer_rel, proj_init_rel, axis_vec));
@@ -274,7 +274,7 @@ fail:
}
static void dial_draw_intern(
- const bContext *C, wmGizmo *mpr,
+ const bContext *C, wmGizmo *gz,
const bool select, const bool highlight, float clip_plane[4])
{
float matrix_basis_adjust[4][4];
@@ -283,30 +283,30 @@ static void dial_draw_intern(
BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D);
- gizmo_color_get(mpr, highlight, color);
+ gizmo_color_get(gz, highlight, color);
- dial_calc_matrix(mpr, matrix_basis_adjust);
+ dial_calc_matrix(gz, matrix_basis_adjust);
WM_gizmo_calc_matrix_final_params(
- mpr, &((struct WM_GizmoMatrixParams) {
+ gz, &((struct WM_GizmoMatrixParams) {
.matrix_basis = (void *)matrix_basis_adjust,
}), matrix_final);
- gpuPushMatrix();
- gpuMultMatrix(matrix_final);
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix_final);
/* draw rotation indicator arc first */
- if ((mpr->flag & WM_GIZMO_DRAW_VALUE) &&
- (mpr->state & WM_GIZMO_STATE_MODAL))
+ if ((gz->flag & WM_GIZMO_DRAW_VALUE) &&
+ (gz->state & WM_GIZMO_STATE_MODAL))
{
const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; /* coordinate at which the arc drawing will be started */
- DialInteraction *inter = mpr->interaction_data;
+ DialInteraction *inter = gz->interaction_data;
/* XXX, View3D rotation gizmo doesn't call modal. */
- if (!WM_gizmo_target_property_is_valid_any(mpr)) {
+ if (!WM_gizmo_target_property_is_valid_any(gz)) {
wmWindow *win = CTX_wm_window(C);
- gizmo_dial_modal((bContext *)C, mpr, win->eventstate, 0);
+ gizmo_dial_modal((bContext *)C, gz, win->eventstate, 0);
}
float angle_ofs = inter->output.angle_ofs;
@@ -315,14 +315,14 @@ static void dial_draw_intern(
/* draw! */
for (int i = 0; i < 2; i++) {
GPU_polygon_smooth(false);
- dial_ghostarc_draw(mpr, angle_ofs, angle_delta, (const float[4]){0.8f, 0.8f, 0.8f, 0.4f});
+ dial_ghostarc_draw(gz, angle_ofs, angle_delta, (const float[4]){0.8f, 0.8f, 0.8f, 0.4f});
GPU_polygon_smooth(true);
dial_ghostarc_draw_helpline(angle_ofs, co_outer, color); /* starting position */
dial_ghostarc_draw_helpline(angle_ofs + angle_delta, co_outer, color); /* starting position + current value */
if (i == 0) {
- const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
if ((draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR) == 0) {
break;
}
@@ -333,15 +333,15 @@ static void dial_draw_intern(
}
/* draw actual dial gizmo */
- dial_geom_draw(mpr, color, select, matrix_basis_adjust, clip_plane);
+ dial_geom_draw(gz, color, select, matrix_basis_adjust, clip_plane);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
-static void gizmo_dial_draw_select(const bContext *C, wmGizmo *mpr, int select_id)
+static void gizmo_dial_draw_select(const bContext *C, wmGizmo *gz, int select_id)
{
float clip_plane_buf[4];
- const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
float *clip_plane = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_CLIP) ? clip_plane_buf : NULL;
/* enable clipping if needed */
@@ -350,25 +350,25 @@ static void gizmo_dial_draw_select(const bContext *C, wmGizmo *mpr, int select_i
RegionView3D *rv3d = ar->regiondata;
copy_v3_v3(clip_plane, rv3d->viewinv[2]);
- clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], mpr->matrix_basis[3]);
- clip_plane[3] += DIAL_CLIP_BIAS * mpr->scale_final;
+ clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], gz->matrix_basis[3]);
+ clip_plane[3] += DIAL_CLIP_BIAS * gz->scale_final;
glEnable(GL_CLIP_DISTANCE0);
}
GPU_select_load_id(select_id);
- dial_draw_intern(C, mpr, true, false, clip_plane);
+ dial_draw_intern(C, gz, true, false, clip_plane);
if (clip_plane) {
glDisable(GL_CLIP_DISTANCE0);
}
}
-static void gizmo_dial_draw(const bContext *C, wmGizmo *mpr)
+static void gizmo_dial_draw(const bContext *C, wmGizmo *gz)
{
- const bool is_modal = mpr->state & WM_GIZMO_STATE_MODAL;
- const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
+ const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL;
+ const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
float clip_plane_buf[4];
- const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
float *clip_plane = (!is_modal && (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_CLIP)) ? clip_plane_buf : NULL;
/* enable clipping if needed */
@@ -377,14 +377,14 @@ static void gizmo_dial_draw(const bContext *C, wmGizmo *mpr)
RegionView3D *rv3d = ar->regiondata;
copy_v3_v3(clip_plane, rv3d->viewinv[2]);
- clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], mpr->matrix_basis[3]);
- clip_plane[3] += DIAL_CLIP_BIAS * mpr->scale_final;
+ clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], gz->matrix_basis[3]);
+ clip_plane[3] += DIAL_CLIP_BIAS * gz->scale_final;
glEnable(GL_CLIP_DISTANCE0);
}
GPU_blend(true);
- dial_draw_intern(C, mpr, false, is_highlight, clip_plane);
+ dial_draw_intern(C, gz, false, is_highlight, clip_plane);
GPU_blend(false);
if (clip_plane) {
@@ -393,7 +393,7 @@ static void gizmo_dial_draw(const bContext *C, wmGizmo *mpr)
}
static int gizmo_dial_modal(
- bContext *C, wmGizmo *mpr, const wmEvent *event,
+ bContext *C, wmGizmo *gz, const wmEvent *event,
eWM_GizmoFlagTweak UNUSED(tweak_flag))
{
const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; /* coordinate at which the arc drawing will be started */
@@ -401,48 +401,48 @@ static int gizmo_dial_modal(
float matrix[4][4];
- dial_calc_matrix(mpr, matrix);
+ dial_calc_matrix(gz, matrix);
dial_ghostarc_get_angles(
CTX_data_depsgraph(C),
- mpr, event, CTX_wm_region(C), CTX_wm_view3d(C), matrix, co_outer, &angle_ofs, &angle_delta);
+ gz, event, CTX_wm_region(C), CTX_wm_view3d(C), matrix, co_outer, &angle_ofs, &angle_delta);
- DialInteraction *inter = mpr->interaction_data;
+ DialInteraction *inter = gz->interaction_data;
inter->output.angle_delta = angle_delta;
inter->output.angle_ofs = angle_ofs;
/* set the property for the operator and call its modal function */
- wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset");
- if (WM_gizmo_target_property_is_valid(mpr_prop)) {
- WM_gizmo_target_property_value_set(C, mpr, mpr_prop, inter->init_prop_angle + angle_delta);
+ wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
+ if (WM_gizmo_target_property_is_valid(gz_prop)) {
+ WM_gizmo_target_property_value_set(C, gz, gz_prop, inter->init_prop_angle + angle_delta);
}
return OPERATOR_RUNNING_MODAL;
}
-static void gizmo_dial_setup(wmGizmo *mpr)
+static void gizmo_dial_setup(wmGizmo *gz)
{
const float dir_default[3] = {0.0f, 0.0f, 1.0f};
/* defaults */
- copy_v3_v3(mpr->matrix_basis[2], dir_default);
+ copy_v3_v3(gz->matrix_basis[2], dir_default);
}
static int gizmo_dial_invoke(
- bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event)
+ bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event)
{
DialInteraction *inter = MEM_callocN(sizeof(DialInteraction), __func__);
inter->init_mval[0] = event->mval[0];
inter->init_mval[1] = event->mval[1];
- wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset");
- if (WM_gizmo_target_property_is_valid(mpr_prop)) {
- inter->init_prop_angle = WM_gizmo_target_property_value_get(mpr, mpr_prop);
+ wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
+ if (WM_gizmo_target_property_is_valid(gz_prop)) {
+ inter->init_prop_angle = WM_gizmo_target_property_value_get(gz, gz_prop);
}
- mpr->interaction_data = inter;
+ gz->interaction_data = inter;
return OPERATOR_RUNNING_MODAL;
}
@@ -452,19 +452,19 @@ static int gizmo_dial_invoke(
*
* \{ */
-static void GIZMO_WT_dial_3d(wmGizmoType *wt)
+static void GIZMO_GT_dial_3d(wmGizmoType *gzt)
{
/* identifiers */
- wt->idname = "GIZMO_WT_dial_3d";
+ gzt->idname = "GIZMO_GT_dial_3d";
/* api callbacks */
- wt->draw = gizmo_dial_draw;
- wt->draw_select = gizmo_dial_draw_select;
- wt->setup = gizmo_dial_setup;
- wt->invoke = gizmo_dial_invoke;
- wt->modal = gizmo_dial_modal;
+ gzt->draw = gizmo_dial_draw;
+ gzt->draw_select = gizmo_dial_draw_select;
+ gzt->setup = gizmo_dial_setup;
+ gzt->invoke = gizmo_dial_invoke;
+ gzt->modal = gizmo_dial_modal;
- wt->struct_size = sizeof(wmGizmo);
+ gzt->struct_size = sizeof(wmGizmo);
/* rna */
static EnumPropertyItem rna_enum_draw_options[] = {
@@ -474,14 +474,14 @@ static void GIZMO_WT_dial_3d(wmGizmoType *wt)
{ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y, "ANGLE_START_Y", 0, "Angle Start Y", ""},
{0, NULL, 0, NULL, NULL}
};
- RNA_def_enum_flag(wt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", "");
+ RNA_def_enum_flag(gzt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", "");
- WM_gizmotype_target_property_def(wt, "offset", PROP_FLOAT, 1);
+ WM_gizmotype_target_property_def(gzt, "offset", PROP_FLOAT, 1);
}
void ED_gizmotypes_dial_3d(void)
{
- WM_gizmotype_append(GIZMO_WT_dial_3d);
+ WM_gizmotype_append(GIZMO_GT_dial_3d);
}
/** \} */
diff --git a/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c
index 2a89c8cc4ab..fcbd333078d 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c
@@ -68,16 +68,16 @@ typedef struct GrabGizmo3D {
float prop_co[3];
} GrabGizmo3D;
-static void gizmo_grab_matrix_basis_get(const wmGizmo *mpr, float r_matrix[4][4])
+static void gizmo_grab_matrix_basis_get(const wmGizmo *gz, float r_matrix[4][4])
{
- GrabGizmo3D *grab = (GrabGizmo3D *)mpr;
+ GrabGizmo3D *grab = (GrabGizmo3D *)gz;
copy_m4_m4(r_matrix, grab->gizmo.matrix_basis);
add_v3_v3(r_matrix[3], grab->prop_co);
}
static int gizmo_grab_modal(
- bContext *C, wmGizmo *mpr, const wmEvent *event,
+ bContext *C, wmGizmo *gz, const wmEvent *event,
eWM_GizmoFlagTweak tweak_flag);
typedef struct GrabInteraction {
@@ -94,19 +94,19 @@ typedef struct GrabInteraction {
/* -------------------------------------------------------------------- */
static void grab_geom_draw(
- const wmGizmo *mpr, const float color[4], const bool select, const int draw_options)
+ const wmGizmo *gz, const float color[4], const bool select, const int draw_options)
{
#ifdef USE_GIZMO_CUSTOM_DIAL
UNUSED_VARS(grab3d, col, axis_modal_mat);
wm_gizmo_geometryinfo_draw(&wm_gizmo_geom_data_grab3d, select);
#else
- const int draw_style = RNA_enum_get(mpr->ptr, "draw_style");
+ const int draw_style = RNA_enum_get(gz->ptr, "draw_style");
const bool filled = (draw_options & ED_GIZMO_GRAB_DRAW_FLAG_FILL) != 0;
- GPU_line_width(mpr->line_width);
+ GPU_line_width(gz->line_width);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -121,7 +121,7 @@ static void grab_geom_draw(
}
}
else if (draw_style == ED_GIZMO_GRAB_STYLE_CROSS_2D) {
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, 1.0f, 1.0f);
immVertex2f(pos, -1.0f, -1.0f);
@@ -140,10 +140,10 @@ static void grab_geom_draw(
}
static void grab3d_get_translate(
- const wmGizmo *mpr, const wmEvent *event, const ARegion *ar,
+ const wmGizmo *gz, const wmEvent *event, const ARegion *ar,
float co_delta[3])
{
- GrabInteraction *inter = mpr->interaction_data;
+ GrabInteraction *inter = gz->interaction_data;
const float mval_delta[2] = {
event->mval[0] - inter->init_mval[0],
event->mval[1] - inter->init_mval[1],
@@ -151,33 +151,33 @@ static void grab3d_get_translate(
RegionView3D *rv3d = ar->regiondata;
float co_ref[3];
- mul_v3_mat3_m4v3(co_ref, mpr->matrix_space, inter->init_prop_co);
+ mul_v3_mat3_m4v3(co_ref, gz->matrix_space, inter->init_prop_co);
const float zfac = ED_view3d_calc_zfac(rv3d, co_ref, NULL);
ED_view3d_win_to_delta(ar, mval_delta, co_delta, zfac);
float matrix_space_inv[3][3];
- copy_m3_m4(matrix_space_inv, mpr->matrix_space);
+ copy_m3_m4(matrix_space_inv, gz->matrix_space);
invert_m3(matrix_space_inv);
mul_m3_v3(matrix_space_inv, co_delta);
}
static void grab3d_draw_intern(
- const bContext *C, wmGizmo *mpr,
+ const bContext *C, wmGizmo *gz,
const bool select, const bool highlight)
{
- GrabInteraction *inter = mpr->interaction_data;
- const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ GrabInteraction *inter = gz->interaction_data;
+ const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
const bool align_view = (draw_options & ED_GIZMO_GRAB_DRAW_FLAG_ALIGN_VIEW) != 0;
float color[4];
float matrix_final[4][4];
float matrix_align[4][4];
- gizmo_color_get(mpr, highlight, color);
- WM_gizmo_calc_matrix_final(mpr, matrix_final);
+ gizmo_color_get(gz, highlight, color);
+ WM_gizmo_calc_matrix_final(gz, matrix_final);
- gpuPushMatrix();
- gpuMultMatrix(matrix_final);
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix_final);
if (align_view) {
float matrix_final_unit[4][4];
@@ -186,65 +186,65 @@ static void grab3d_draw_intern(
mul_m4_m4m4(matrix_align, rv3d->viewmat, matrix_final_unit);
zero_v3(matrix_align[3]);
transpose_m4(matrix_align);
- gpuMultMatrix(matrix_align);
+ GPU_matrix_mul(matrix_align);
}
GPU_blend(true);
- grab_geom_draw(mpr, color, select, draw_options);
+ grab_geom_draw(gz, color, select, draw_options);
GPU_blend(false);
- gpuPopMatrix();
+ GPU_matrix_pop();
- if (mpr->interaction_data) {
- gpuPushMatrix();
- gpuMultMatrix(inter->init_matrix_final);
+ if (gz->interaction_data) {
+ GPU_matrix_push();
+ GPU_matrix_mul(inter->init_matrix_final);
if (align_view) {
- gpuMultMatrix(matrix_align);
+ GPU_matrix_mul(matrix_align);
}
GPU_blend(true);
- grab_geom_draw(mpr, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}, select, draw_options);
+ grab_geom_draw(gz, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}, select, draw_options);
GPU_blend(false);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
-static void gizmo_grab_draw_select(const bContext *C, wmGizmo *mpr, int select_id)
+static void gizmo_grab_draw_select(const bContext *C, wmGizmo *gz, int select_id)
{
GPU_select_load_id(select_id);
- grab3d_draw_intern(C, mpr, true, false);
+ grab3d_draw_intern(C, gz, true, false);
}
-static void gizmo_grab_draw(const bContext *C, wmGizmo *mpr)
+static void gizmo_grab_draw(const bContext *C, wmGizmo *gz)
{
- const bool is_modal = mpr->state & WM_GIZMO_STATE_MODAL;
- const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
+ const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL;
+ const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
(void)is_modal;
GPU_blend(true);
- grab3d_draw_intern(C, mpr, false, is_highlight);
+ grab3d_draw_intern(C, gz, false, is_highlight);
GPU_blend(false);
}
static int gizmo_grab_modal(
- bContext *C, wmGizmo *mpr, const wmEvent *event,
+ bContext *C, wmGizmo *gz, const wmEvent *event,
eWM_GizmoFlagTweak UNUSED(tweak_flag))
{
- GrabGizmo3D *grab = (GrabGizmo3D *)mpr;
- GrabInteraction *inter = mpr->interaction_data;
+ GrabGizmo3D *grab = (GrabGizmo3D *)gz;
+ GrabInteraction *inter = gz->interaction_data;
ARegion *ar = CTX_wm_region(C);
float prop_delta[3];
if (CTX_wm_area(C)->spacetype == SPACE_VIEW3D) {
- grab3d_get_translate(mpr, event, ar, prop_delta);
+ grab3d_get_translate(gz, event, ar, prop_delta);
}
else {
float mval_proj_init[2], mval_proj_curr[2];
if ((gizmo_window_project_2d(
- C, mpr, inter->init_mval, 2, false, mval_proj_init) == false) ||
+ C, gz, inter->init_mval, 2, false, mval_proj_init) == false) ||
(gizmo_window_project_2d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, mval_proj_curr) == false))
+ C, gz, (const float[2]){UNPACK2(event->mval)}, 2, false, mval_proj_curr) == false))
{
return OPERATOR_RUNNING_MODAL;
}
@@ -254,9 +254,9 @@ static int gizmo_grab_modal(
add_v3_v3v3(grab->prop_co, inter->init_prop_co, prop_delta);
/* set the property for the operator and call its modal function */
- wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset");
- if (WM_gizmo_target_property_is_valid(mpr_prop)) {
- WM_gizmo_target_property_value_set_array(C, mpr, mpr_prop, grab->prop_co);
+ wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
+ if (WM_gizmo_target_property_is_valid(gz_prop)) {
+ WM_gizmo_target_property_value_set_array(C, gz, gz_prop, grab->prop_co);
}
else {
zero_v3(grab->prop_co);
@@ -268,7 +268,7 @@ static int gizmo_grab_modal(
}
static int gizmo_grab_invoke(
- bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event)
+ bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event)
{
GrabInteraction *inter = MEM_callocN(sizeof(GrabInteraction), __func__);
@@ -278,32 +278,32 @@ static int gizmo_grab_invoke(
#if 0
copy_v3_v3(inter->init_prop_co, grab->prop_co);
#else
- wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset");
- if (WM_gizmo_target_property_is_valid(mpr_prop)) {
- WM_gizmo_target_property_value_get_array(mpr, mpr_prop, inter->init_prop_co);
+ wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
+ if (WM_gizmo_target_property_is_valid(gz_prop)) {
+ WM_gizmo_target_property_value_get_array(gz, gz_prop, inter->init_prop_co);
}
#endif
- WM_gizmo_calc_matrix_final(mpr, inter->init_matrix_final);
+ WM_gizmo_calc_matrix_final(gz, inter->init_matrix_final);
- mpr->interaction_data = inter;
+ gz->interaction_data = inter;
return OPERATOR_RUNNING_MODAL;
}
static int gizmo_grab_test_select(
- bContext *C, wmGizmo *mpr, const wmEvent *event)
+ bContext *C, wmGizmo *gz, const int mval[2])
{
float point_local[2];
if (gizmo_window_project_2d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false)
+ C, gz, (const float[2]){UNPACK2(mval)}, 2, true, point_local) == false)
{
return -1;
}
- /* The 'mpr->scale_final' is already applied when projecting. */
+ /* The 'gz->scale_final' is already applied when projecting. */
if (len_squared_v2(point_local) < 1.0f) {
return 0;
}
@@ -311,18 +311,18 @@ static int gizmo_grab_test_select(
return -1;
}
-static void gizmo_grab_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop)
+static void gizmo_grab_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop)
{
- GrabGizmo3D *grab = (GrabGizmo3D *)mpr;
- if (WM_gizmo_target_property_is_valid(mpr_prop)) {
- WM_gizmo_target_property_value_get_array(mpr, mpr_prop, grab->prop_co);
+ GrabGizmo3D *grab = (GrabGizmo3D *)gz;
+ if (WM_gizmo_target_property_is_valid(gz_prop)) {
+ WM_gizmo_target_property_value_get_array(gz, gz_prop, grab->prop_co);
}
else {
zero_v3(grab->prop_co);
}
}
-static int gizmo_grab_cursor_get(wmGizmo *UNUSED(mpr))
+static int gizmo_grab_cursor_get(wmGizmo *UNUSED(gz))
{
return BC_NSEW_SCROLLCURSOR;
}
@@ -332,22 +332,22 @@ static int gizmo_grab_cursor_get(wmGizmo *UNUSED(mpr))
*
* \{ */
-static void GIZMO_WT_grab_3d(wmGizmoType *wt)
+static void GIZMO_GT_grab_3d(wmGizmoType *gzt)
{
/* identifiers */
- wt->idname = "GIZMO_WT_grab_3d";
+ gzt->idname = "GIZMO_GT_grab_3d";
/* api callbacks */
- wt->draw = gizmo_grab_draw;
- wt->draw_select = gizmo_grab_draw_select;
- wt->test_select = gizmo_grab_test_select;
- wt->matrix_basis_get = gizmo_grab_matrix_basis_get;
- wt->invoke = gizmo_grab_invoke;
- wt->property_update = gizmo_grab_property_update;
- wt->modal = gizmo_grab_modal;
- wt->cursor_get = gizmo_grab_cursor_get;
+ gzt->draw = gizmo_grab_draw;
+ gzt->draw_select = gizmo_grab_draw_select;
+ gzt->test_select = gizmo_grab_test_select;
+ gzt->matrix_basis_get = gizmo_grab_matrix_basis_get;
+ gzt->invoke = gizmo_grab_invoke;
+ gzt->property_update = gizmo_grab_property_update;
+ gzt->modal = gizmo_grab_modal;
+ gzt->cursor_get = gizmo_grab_cursor_get;
- wt->struct_size = sizeof(GrabGizmo3D);
+ gzt->struct_size = sizeof(GrabGizmo3D);
/* rna */
static EnumPropertyItem rna_enum_draw_style[] = {
@@ -361,15 +361,15 @@ static void GIZMO_WT_grab_3d(wmGizmoType *wt)
{0, NULL, 0, NULL, NULL}
};
- RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_GRAB_STYLE_RING_2D, "Draw Style", "");
- RNA_def_enum_flag(wt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", "");
+ RNA_def_enum(gzt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_GRAB_STYLE_RING_2D, "Draw Style", "");
+ RNA_def_enum_flag(gzt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", "");
- WM_gizmotype_target_property_def(wt, "offset", PROP_FLOAT, 3);
+ WM_gizmotype_target_property_def(gzt, "offset", PROP_FLOAT, 3);
}
void ED_gizmotypes_grab_3d(void)
{
- WM_gizmotype_append(GIZMO_WT_grab_3d);
+ WM_gizmotype_append(GIZMO_GT_grab_3d);
}
/** \} */ // Grab Gizmo API
diff --git a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c
index ff02517dafa..6443a6bf038 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c
@@ -77,83 +77,83 @@ static void gizmo_primitive_draw_geom(
}
if (vert_count > 0) {
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- wm_gizmo_vec_draw(col_inner, verts, vert_count, pos, GWN_PRIM_TRI_FAN);
- wm_gizmo_vec_draw(col_outer, verts, vert_count, pos, GWN_PRIM_LINE_LOOP);
+ wm_gizmo_vec_draw(col_inner, verts, vert_count, pos, GPU_PRIM_TRI_FAN);
+ wm_gizmo_vec_draw(col_outer, verts, vert_count, pos, GPU_PRIM_LINE_LOOP);
immUnbindProgram();
}
}
static void gizmo_primitive_draw_intern(
- wmGizmo *mpr, const bool UNUSED(select),
+ wmGizmo *gz, const bool UNUSED(select),
const bool highlight)
{
float color_inner[4], color_outer[4];
float matrix_final[4][4];
- const int draw_style = RNA_enum_get(mpr->ptr, "draw_style");
+ const int draw_style = RNA_enum_get(gz->ptr, "draw_style");
- gizmo_color_get(mpr, highlight, color_outer);
+ gizmo_color_get(gz, highlight, color_outer);
copy_v4_v4(color_inner, color_outer);
color_inner[3] *= 0.5f;
- WM_gizmo_calc_matrix_final(mpr, matrix_final);
+ WM_gizmo_calc_matrix_final(gz, matrix_final);
- gpuPushMatrix();
- gpuMultMatrix(matrix_final);
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix_final);
GPU_blend(true);
gizmo_primitive_draw_geom(color_inner, color_outer, draw_style);
GPU_blend(false);
- gpuPopMatrix();
+ GPU_matrix_pop();
- if (mpr->interaction_data) {
- GizmoInteraction *inter = mpr->interaction_data;
+ if (gz->interaction_data) {
+ GizmoInteraction *inter = gz->interaction_data;
copy_v4_fl(color_inner, 0.5f);
copy_v3_fl(color_outer, 0.5f);
color_outer[3] = 0.8f;
- gpuPushMatrix();
- gpuMultMatrix(inter->init_matrix_final);
+ GPU_matrix_push();
+ GPU_matrix_mul(inter->init_matrix_final);
GPU_blend(true);
gizmo_primitive_draw_geom(color_inner, color_outer, draw_style);
GPU_blend(false);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
static void gizmo_primitive_draw_select(
- const bContext *UNUSED(C), wmGizmo *mpr,
+ const bContext *UNUSED(C), wmGizmo *gz,
int select_id)
{
GPU_select_load_id(select_id);
- gizmo_primitive_draw_intern(mpr, true, false);
+ gizmo_primitive_draw_intern(gz, true, false);
}
-static void gizmo_primitive_draw(const bContext *UNUSED(C), wmGizmo *mpr)
+static void gizmo_primitive_draw(const bContext *UNUSED(C), wmGizmo *gz)
{
gizmo_primitive_draw_intern(
- mpr, false,
- (mpr->state & WM_GIZMO_STATE_HIGHLIGHT));
+ gz, false,
+ (gz->state & WM_GIZMO_STATE_HIGHLIGHT));
}
-static void gizmo_primitive_setup(wmGizmo *mpr)
+static void gizmo_primitive_setup(wmGizmo *gz)
{
- mpr->flag |= WM_GIZMO_DRAW_MODAL;
+ gz->flag |= WM_GIZMO_DRAW_MODAL;
}
static int gizmo_primitive_invoke(
- bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *UNUSED(event))
+ bContext *UNUSED(C), wmGizmo *gz, const wmEvent *UNUSED(event))
{
GizmoInteraction *inter = MEM_callocN(sizeof(GizmoInteraction), __func__);
- WM_gizmo_calc_matrix_final(mpr, inter->init_matrix_final);
+ WM_gizmo_calc_matrix_final(gz, inter->init_matrix_final);
- mpr->interaction_data = inter;
+ gz->interaction_data = inter;
return OPERATOR_RUNNING_MODAL;
}
@@ -163,29 +163,29 @@ static int gizmo_primitive_invoke(
*
* \{ */
-static void GIZMO_WT_primitive_3d(wmGizmoType *wt)
+static void GIZMO_GT_primitive_3d(wmGizmoType *gzt)
{
/* identifiers */
- wt->idname = "GIZMO_WT_primitive_3d";
+ gzt->idname = "GIZMO_GT_primitive_3d";
/* api callbacks */
- wt->draw = gizmo_primitive_draw;
- wt->draw_select = gizmo_primitive_draw_select;
- wt->setup = gizmo_primitive_setup;
- wt->invoke = gizmo_primitive_invoke;
+ gzt->draw = gizmo_primitive_draw;
+ gzt->draw_select = gizmo_primitive_draw_select;
+ gzt->setup = gizmo_primitive_setup;
+ gzt->invoke = gizmo_primitive_invoke;
- wt->struct_size = sizeof(wmGizmo);
+ gzt->struct_size = sizeof(wmGizmo);
static EnumPropertyItem rna_enum_draw_style[] = {
{ED_GIZMO_PRIMITIVE_STYLE_PLANE, "PLANE", 0, "Plane", ""},
{0, NULL, 0, NULL, NULL}
};
- RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_PRIMITIVE_STYLE_PLANE, "Draw Style", "");
+ RNA_def_enum(gzt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_PRIMITIVE_STYLE_PLANE, "Draw Style", "");
}
void ED_gizmotypes_primitive_3d(void)
{
- WM_gizmotype_append(GIZMO_WT_primitive_3d);
+ WM_gizmotype_append(GIZMO_GT_primitive_3d);
}
/** \} */
diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt
index 587c25031ab..114e55c5704 100644
--- a/source/blender/editors/gpencil/CMakeLists.txt
+++ b/source/blender/editors/gpencil/CMakeLists.txt
@@ -39,18 +39,25 @@ set(INC_SYS
)
set(SRC
+ annotate_draw.c
+ annotate_paint.c
drawgpencil.c
editaction_gpencil.c
+ gpencil_add_monkey.c
+ gpencil_add_stroke.c
gpencil_brush.c
gpencil_convert.c
gpencil_data.c
gpencil_edit.c
gpencil_interpolate.c
+ gpencil_primitive.c
gpencil_ops.c
gpencil_paint.c
+ gpencil_fill.c
gpencil_select.c
gpencil_undo.c
gpencil_utils.c
+ gpencil_old.c
gpencil_intern.h
)
diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c
new file mode 100644
index 00000000000..4f6e2004197
--- /dev/null
+++ b/source/blender/editors/gpencil/annotate_draw.c
@@ -0,0 +1,1066 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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
+ *
+ * Contributor(s): Joshua Leung, Antonio Vazquez
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/gpencil/annotate_draw.c
+ * \ingroup edgpencil
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <math.h>
+#include <float.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_sys_types.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_polyfill_2d.h"
+
+#include "BLF_api.h"
+#include "BLT_translation.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_gpencil.h"
+
+#include "WM_api.h"
+
+#include "BIF_glutil.h"
+
+#include "GPU_immediate.h"
+#include "GPU_draw.h"
+#include "GPU_state.h"
+
+#include "ED_gpencil.h"
+#include "ED_screen.h"
+#include "ED_view3d.h"
+#include "ED_space_api.h"
+
+#include "UI_interface_icons.h"
+#include "UI_resources.h"
+
+/* ************************************************** */
+/* GREASE PENCIL DRAWING */
+
+/* ----- General Defines ------ */
+/* flags for sflag */
+typedef enum eDrawStrokeFlags {
+ GP_DRAWDATA_NOSTATUS = (1 << 0), /* don't draw status info */
+ GP_DRAWDATA_ONLY3D = (1 << 1), /* only draw 3d-strokes */
+ GP_DRAWDATA_ONLYV2D = (1 << 2), /* only draw 'canvas' strokes */
+ GP_DRAWDATA_ONLYI2D = (1 << 3), /* only draw 'image' strokes */
+ GP_DRAWDATA_IEDITHACK = (1 << 4), /* special hack for drawing strokes in Image Editor (weird coordinates) */
+ GP_DRAWDATA_NO_XRAY = (1 << 5), /* don't draw xray in 3D view (which is default) */
+ GP_DRAWDATA_NO_ONIONS = (1 << 6), /* no onionskins should be drawn (for animation playback) */
+} eDrawStrokeFlags;
+
+
+/* ----- Tool Buffer Drawing ------ */
+
+/* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */
+static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short thickness,
+ short dflag, short sflag, float ink[4])
+{
+ int draw_points = 0;
+
+ /* error checking */
+ if ((points == NULL) || (totpoints <= 0))
+ return;
+
+ /* check if buffer can be drawn */
+ if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D))
+ return;
+
+ if (sflag & GP_STROKE_ERASER) {
+ /* don't draw stroke at all! */
+ return;
+ }
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+
+ const tGPspoint *pt = points;
+
+ if (totpoints == 1) {
+ /* if drawing a single point, draw it larger */
+ GPU_point_size((float)(thickness + 2) * points->pressure);
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+ immUniformColor3fvAlpha(ink, ink[3]);
+ immBegin(GPU_PRIM_POINTS, 1);
+ immVertex2iv(pos, &pt->x);
+ }
+ else {
+ float oldpressure = points[0].pressure;
+
+ /* draw stroke curve */
+ GPU_line_width(max_ff(oldpressure * thickness, 1.0));
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3fvAlpha(ink, ink[3]);
+
+ /* TODO: implement this with a geometry shader to draw one continuous tapered stroke */
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints);
+
+ for (int i = 0; i < totpoints; i++, pt++) {
+ /* if there was a significant pressure change, stop the curve, change the thickness of the stroke,
+ * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP)
+ */
+ if (fabsf(pt->pressure - oldpressure) > 0.2f) {
+ /* need to have 2 points to avoid immEnd assert error */
+ if (draw_points < 2) {
+ immVertex2iv(pos, &(pt - 1)->x);
+ }
+
+ immEnd();
+ draw_points = 0;
+
+ GPU_line_width(max_ff(pt->pressure * thickness, 1.0f));
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1);
+
+ /* need to roll-back one point to ensure that there are no gaps in the stroke */
+ if (i != 0) {
+ immVertex2iv(pos, &(pt - 1)->x);
+ draw_points++;
+ }
+
+ oldpressure = pt->pressure; /* reset our threshold */
+ }
+
+ /* now the point we want */
+ immVertex2iv(pos, &pt->x);
+ draw_points++;
+ }
+ /* need to have 2 points to avoid immEnd assert error */
+ if (draw_points < 2) {
+ immVertex2iv(pos, &(pt - 1)->x);
+ }
+ }
+
+ immEnd();
+ immUnbindProgram();
+}
+
+/* --------- 2D Stroke Drawing Helpers --------- */
+/* change in parameter list */
+static void gp_calc_2d_stroke_fxy(const float pt[3], short sflag, int offsx, int offsy, int winx, int winy, float r_co[2])
+{
+ if (sflag & GP_STROKE_2DSPACE) {
+ r_co[0] = pt[0];
+ r_co[1] = pt[1];
+ }
+ else if (sflag & GP_STROKE_2DIMAGE) {
+ const float x = (float)((pt[0] * winx) + offsx);
+ const float y = (float)((pt[1] * winy) + offsy);
+
+ r_co[0] = x;
+ r_co[1] = y;
+ }
+ else {
+ const float x = (float)(pt[0] / 100 * winx) + offsx;
+ const float y = (float)(pt[1] / 100 * winy) + offsy;
+
+ r_co[0] = x;
+ r_co[1] = y;
+ }
+}
+
+/* ----- Existing Strokes Drawing (3D and Point) ------ */
+
+/* draw a given stroke - just a single dot (only one point) */
+static void gp_draw_stroke_point(
+ const bGPDspoint *points, short thickness, short UNUSED(dflag), short sflag,
+ int offsx, int offsy, int winx, int winy, const float ink[4])
+{
+ const bGPDspoint *pt = points;
+
+ /* get final position using parent matrix */
+ float fpt[3];
+ copy_v3_v3(fpt, &pt->x);
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+
+ if (sflag & GP_STROKE_3DSPACE) {
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+
+ /* get 2D coordinates of point */
+ float co[3] = { 0.0f };
+ gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, co);
+ copy_v3_v3(fpt, co);
+ }
+
+ /* set color */
+ immUniformColor3fvAlpha(ink, ink[3]);
+
+ /* set point thickness (since there's only one of these) */
+ immUniform1f("size", (float)(thickness + 2) * pt->pressure);
+
+ immBegin(GPU_PRIM_POINTS, 1);
+ immVertex3fv(pos, fpt);
+ immEnd();
+
+ immUnbindProgram();
+}
+
+/* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */
+static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thickness, bool UNUSED(debug),
+ short UNUSED(sflag), const float ink[4], bool cyclic)
+{
+ float curpressure = points[0].pressure;
+ float cyclic_fpt[3];
+ int draw_points = 0;
+
+ /* if cyclic needs one vertex more */
+ int cyclic_add = 0;
+ if (cyclic) {
+ cyclic_add++;
+ }
+
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3fvAlpha(ink, ink[3]);
+
+ /* TODO: implement this with a geometry shader to draw one continuous tapered stroke */
+
+ /* 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++) {
+ /* if there was a significant pressure change, stop the curve, change the thickness of the stroke,
+ * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP)
+ * Note: we want more visible levels of pressures when thickness is bigger.
+ */
+ if (fabsf(pt->pressure - curpressure) > 0.2f / (float)thickness) {
+ /* if the pressure changes before get at least 2 vertices, need to repeat last point to avoid assert in immEnd() */
+ if (draw_points < 2) {
+ const bGPDspoint *pt2 = pt - 1;
+ immVertex3fv(pos, &pt2->x);
+ }
+ immEnd();
+ draw_points = 0;
+
+ curpressure = pt->pressure;
+ GPU_line_width(max_ff(curpressure * thickness, 1.0f));
+ 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 */
+ if (i != 0) {
+ const bGPDspoint *pt2 = pt - 1;
+ immVertex3fv(pos, &pt2->x);
+ draw_points++;
+ }
+ }
+
+ /* now the point we want */
+ immVertex3fv(pos, &pt->x);
+ draw_points++;
+
+ if (cyclic && i == 0) {
+ /* save first point to use in cyclic */
+ copy_v3_v3(cyclic_fpt, &pt->x);
+ }
+ }
+
+ if (cyclic) {
+ /* draw line to first point to complete the cycle */
+ immVertex3fv(pos, cyclic_fpt);
+ draw_points++;
+ }
+
+ /* if less of two points, need to repeat last point to avoid assert in immEnd() */
+ if (draw_points < 2) {
+ const bGPDspoint *pt2 = pt - 1;
+ immVertex3fv(pos, &pt2->x);
+ }
+
+ immEnd();
+ immUnbindProgram();
+}
+
+/* ----- Fancy 2D-Stroke Drawing ------ */
+
+/* draw a given stroke in 2d */
+static void gp_draw_stroke_2d(const bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag,
+ bool UNUSED(debug), int offsx, int offsy, int winx, int winy, const float ink[4])
+{
+ /* otherwise thickness is twice that of the 3D view */
+ float thickness = (float)thickness_s * 0.5f;
+
+ /* strokes in Image Editor need a scale factor, since units there are not pixels! */
+ float scalefac = 1.0f;
+ if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) {
+ scalefac = 0.001f;
+ }
+
+ /* TODO: fancy++ with the magic of shaders */
+
+ /* tessellation code - draw stroke as series of connected quads (triangle strips in fact) with connection
+ * edges rotated to minimize shrinking artifacts, and rounded endcaps
+ */
+ {
+ const bGPDspoint *pt1, *pt2;
+ float s0[2], s1[2]; /* segment 'center' points */
+ float pm[2]; /* normal from previous segment. */
+ int i;
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3fvAlpha(ink, ink[3]);
+ immBegin(GPU_PRIM_TRI_STRIP, totpoints * 2 + 4);
+
+ /* get x and y coordinates from first point */
+ gp_calc_2d_stroke_fxy(&points->x, sflag, offsx, offsy, winx, winy, s0);
+
+ for (i = 0, pt1 = points, pt2 = points + 1; i < (totpoints - 1); i++, pt1++, pt2++) {
+ float t0[2], t1[2]; /* tessellated coordinates */
+ float m1[2], m2[2]; /* gradient and normal */
+ float mt[2], sc[2]; /* gradient for thickness, point for end-cap */
+ float pthick; /* thickness at segment point */
+
+ /* get x and y coordinates from point2 (point1 has already been computed in previous iteration). */
+ gp_calc_2d_stroke_fxy(&pt2->x, sflag, offsx, offsy, winx, winy, s1);
+
+ /* calculate gradient and normal - 'angle'=(ny/nx) */
+ m1[1] = s1[1] - s0[1];
+ m1[0] = s1[0] - s0[0];
+ normalize_v2(m1);
+ m2[1] = -m1[0];
+ m2[0] = m1[1];
+
+ /* always use pressure from first point here */
+ pthick = (pt1->pressure * thickness * scalefac);
+
+ /* if the first segment, start of segment is segment's normal */
+ if (i == 0) {
+ /* draw start cap first
+ * - make points slightly closer to center (about halfway across)
+ */
+ mt[0] = m2[0] * pthick * 0.5f;
+ mt[1] = m2[1] * pthick * 0.5f;
+ sc[0] = s0[0] - (m1[0] * pthick * 0.75f);
+ sc[1] = s0[1] - (m1[1] * pthick * 0.75f);
+
+ t0[0] = sc[0] - mt[0];
+ t0[1] = sc[1] - mt[1];
+ t1[0] = sc[0] + mt[0];
+ t1[1] = sc[1] + mt[1];
+
+ /* First two points of cap. */
+ immVertex2fv(pos, t0);
+ immVertex2fv(pos, t1);
+
+ /* calculate points for start of segment */
+ mt[0] = m2[0] * pthick;
+ mt[1] = m2[1] * pthick;
+
+ t0[0] = s0[0] - mt[0];
+ t0[1] = s0[1] - mt[1];
+ t1[0] = s0[0] + mt[0];
+ t1[1] = s0[1] + mt[1];
+
+ /* Last two points of start cap (and first two points of first segment). */
+ immVertex2fv(pos, t0);
+ immVertex2fv(pos, t1);
+ }
+ /* if not the first segment, use bisector of angle between segments */
+ else {
+ float mb[2]; /* bisector normal */
+ float athick, dfac; /* actual thickness, difference between thicknesses */
+
+ /* calculate gradient of bisector (as average of normals) */
+ mb[0] = (pm[0] + m2[0]) / 2;
+ mb[1] = (pm[1] + m2[1]) / 2;
+ normalize_v2(mb);
+
+ /* calculate gradient to apply
+ * - as basis, use just pthick * bisector gradient
+ * - if cross-section not as thick as it should be, add extra padding to fix it
+ */
+ mt[0] = mb[0] * pthick;
+ mt[1] = mb[1] * pthick;
+ athick = len_v2(mt);
+ dfac = pthick - (athick * 2);
+
+ if (((athick * 2.0f) < pthick) && (IS_EQF(athick, pthick) == 0)) {
+ mt[0] += (mb[0] * dfac);
+ mt[1] += (mb[1] * dfac);
+ }
+
+ /* calculate points for start of segment */
+ t0[0] = s0[0] - mt[0];
+ t0[1] = s0[1] - mt[1];
+ t1[0] = s0[0] + mt[0];
+ t1[1] = s0[1] + mt[1];
+
+ /* Last two points of previous segment, and first two points of current segment. */
+ immVertex2fv(pos, t0);
+ immVertex2fv(pos, t1);
+ }
+
+ /* if last segment, also draw end of segment (defined as segment's normal) */
+ if (i == totpoints - 2) {
+ /* for once, we use second point's pressure (otherwise it won't be drawn) */
+ pthick = (pt2->pressure * thickness * scalefac);
+
+ /* calculate points for end of segment */
+ mt[0] = m2[0] * pthick;
+ mt[1] = m2[1] * pthick;
+
+ t0[0] = s1[0] - mt[0];
+ t0[1] = s1[1] - mt[1];
+ t1[0] = s1[0] + mt[0];
+ t1[1] = s1[1] + mt[1];
+
+ /* Last two points of last segment (and first two points of end cap). */
+ immVertex2fv(pos, t0);
+ immVertex2fv(pos, t1);
+
+ /* draw end cap as last step
+ * - make points slightly closer to center (about halfway across)
+ */
+ mt[0] = m2[0] * pthick * 0.5f;
+ mt[1] = m2[1] * pthick * 0.5f;
+ sc[0] = s1[0] + (m1[0] * pthick * 0.75f);
+ sc[1] = s1[1] + (m1[1] * pthick * 0.75f);
+
+ t0[0] = sc[0] - mt[0];
+ t0[1] = sc[1] - mt[1];
+ t1[0] = sc[0] + mt[0];
+ t1[1] = sc[1] + mt[1];
+
+ /* Last two points of end cap. */
+ immVertex2fv(pos, t0);
+ immVertex2fv(pos, t1);
+ }
+
+ /* store computed point2 coordinates as point1 ones of next segment. */
+ copy_v2_v2(s0, s1);
+ /* store stroke's 'natural' normal for next stroke to use */
+ copy_v2_v2(pm, m2);
+ }
+
+ immEnd();
+ immUnbindProgram();
+ }
+}
+
+/* ----- 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)
+{
+ /* skip stroke if it isn't in the right display space for this drawing context */
+ /* 1) 3D Strokes */
+ if ((dflag & GP_DRAWDATA_ONLY3D) && !(gps->flag & GP_STROKE_3DSPACE))
+ return false;
+ if (!(dflag & GP_DRAWDATA_ONLY3D) && (gps->flag & GP_STROKE_3DSPACE))
+ return false;
+
+ /* 2) Screen Space 2D Strokes */
+ if ((dflag & GP_DRAWDATA_ONLYV2D) && !(gps->flag & GP_STROKE_2DSPACE))
+ return false;
+ if (!(dflag & GP_DRAWDATA_ONLYV2D) && (gps->flag & GP_STROKE_2DSPACE))
+ return false;
+
+ /* 3) Image Space (2D) */
+ if ((dflag & GP_DRAWDATA_ONLYI2D) && !(gps->flag & GP_STROKE_2DIMAGE))
+ return false;
+ if (!(dflag & GP_DRAWDATA_ONLYI2D) && (gps->flag & GP_STROKE_2DIMAGE))
+ return false;
+
+ /* skip stroke if it doesn't have any valid data */
+ if ((gps->points == NULL) || (gps->totpoints < 1))
+ return false;
+
+ /* stroke can be drawn */
+ return true;
+}
+
+/* draw a set of strokes */
+static void gp_draw_strokes(
+ bGPdata *UNUSED(gpd), bGPDlayer *UNUSED(gpl), const bGPDframe *gpf, int offsx, int offsy, int winx, int winy,
+ int dflag, bool debug, short lthick, const float color[4])
+{
+ GPU_enable_program_point_size();
+
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* check if stroke can be drawn */
+ if (gp_can_draw_stroke(gps, dflag) == false) {
+ continue;
+ }
+
+ /* check which stroke-drawer to use */
+ if (dflag & GP_DRAWDATA_ONLY3D) {
+ const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY);
+ int mask_orig = 0;
+
+ if (no_xray) {
+ glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
+ glDepthMask(0);
+ GPU_depth_test(true);
+
+ /* first arg is normally rv3d->dist, but this isn't
+ * available here and seems to work quite well without */
+ bglPolygonOffset(1.0f, 1.0f);
+ }
+
+ /* 3D Lines - OpenGL primitives-based */
+ if (gps->totpoints == 1) {
+ gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy, color);
+ }
+ else {
+ gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, debug, gps->flag,
+ color, gps->flag & GP_STROKE_CYCLIC);
+ }
+
+ if (no_xray) {
+ glDepthMask(mask_orig);
+ GPU_depth_test(false);
+
+ bglPolygonOffset(0.0, 0.0);
+ }
+ }
+ else {
+ /* 2D Strokes... */
+ if (gps->totpoints == 1) {
+ gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy, color);
+ }
+ else {
+ gp_draw_stroke_2d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug,
+ offsx, offsy, winx, winy, color);
+ }
+ }
+ }
+
+ GPU_disable_program_point_size();
+}
+
+/* Draw selected verts for strokes being edited */
+static void gp_draw_strokes_edit(
+ bGPdata *gpd, bGPDlayer *gpl, const bGPDframe *gpf,
+ int offsx, int offsy, int winx, int winy,
+ short dflag, short UNUSED(lflag), float alpha)
+{
+ /* if alpha 0 do not draw */
+ if (alpha == 0.0f)
+ return;
+
+ const bool no_xray = (dflag & GP_DRAWDATA_NO_XRAY) != 0;
+ int mask_orig = 0;
+
+ /* set up depth masks... */
+ if (dflag & GP_DRAWDATA_ONLY3D) {
+ if (no_xray) {
+ glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
+ glDepthMask(0);
+ GPU_depth_test(true);
+
+ /* first arg is normally rv3d->dist, but this isn't
+ * available here and seems to work quite well without */
+ bglPolygonOffset(1.0f, 1.0f);
+ }
+ }
+
+ GPU_enable_program_point_size();
+
+ /* draw stroke verts */
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* check if stroke can be drawn */
+ if (gp_can_draw_stroke(gps, dflag) == false)
+ continue;
+
+ /* Optimisation: only draw points for selected strokes
+ * We assume that selected points can only occur in
+ * strokes that are selected too.
+ */
+ if ((gps->flag & GP_STROKE_SELECT) == 0)
+ continue;
+
+ /* Get size of verts:
+ * - The selected state needs to be larger than the unselected state so that
+ * they stand out more.
+ * - We use the theme setting for size of the unselected verts
+ */
+ float bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE);
+ float vsize;
+ if ((int)bsize > 8) {
+ vsize = 10.0f;
+ bsize = 8.0f;
+ }
+ else {
+ vsize = bsize + 2;
+ }
+
+ float selectColor[4];
+ UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor);
+ selectColor[3] = alpha;
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos; /* specified later */
+ uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+
+ if (gps->flag & GP_STROKE_3DSPACE) {
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
+ }
+ else {
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR);
+ }
+
+ immBegin(GPU_PRIM_POINTS, gps->totpoints);
+
+ /* Draw start and end point differently if enabled stroke direction hint */
+ bool show_direction_hint = (gpd->flag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1);
+
+ /* Draw all the stroke points (selected or not) */
+ bGPDspoint *pt = gps->points;
+ for (int i = 0; i < gps->totpoints; i++, pt++) {
+ /* size and color first */
+ if (show_direction_hint && i == 0) {
+ /* start point in green bigger */
+ immAttrib3f(color, 0.0f, 1.0f, 0.0f);
+ immAttrib1f(size, vsize + 4);
+ }
+ else if (show_direction_hint && (i == gps->totpoints - 1)) {
+ /* end point in red smaller */
+ immAttrib3f(color, 1.0f, 0.0f, 0.0f);
+ immAttrib1f(size, vsize + 1);
+ }
+ else if (pt->flag & GP_SPOINT_SELECT) {
+ immAttrib3fv(color, selectColor);
+ immAttrib1f(size, vsize);
+ }
+ else {
+ immAttrib3fv(color, gpl->color);
+ immAttrib1f(size, bsize);
+ }
+
+ /* then position */
+ if (gps->flag & GP_STROKE_3DSPACE) {
+ immVertex3fv(pos, &pt->x);
+ }
+ else {
+ float co[2];
+ gp_calc_2d_stroke_fxy(&pt->x, gps->flag, offsx, offsy, winx, winy, co);
+ immVertex2fv(pos, co);
+ }
+ }
+
+ immEnd();
+ immUnbindProgram();
+ }
+
+ GPU_disable_program_point_size();
+
+ /* clear depth mask */
+ if (dflag & GP_DRAWDATA_ONLY3D) {
+ if (no_xray) {
+ glDepthMask(mask_orig);
+ GPU_depth_test(false);
+
+ bglPolygonOffset(0.0, 0.0);
+#if 0
+ glDisable(GL_POLYGON_OFFSET_LINE);
+ glPolygonOffset(0, 0);
+#endif
+ }
+ }
+}
+
+/* ----- General Drawing ------ */
+
+/* loop over gpencil data layers, drawing them */
+static void gp_draw_data_layers(
+ bGPdata *gpd, int offsx, int offsy, int winx, int winy,
+ int cfra, int dflag, float alpha)
+{
+ float ink[4];
+
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ bool debug = (gpl->flag & GP_LAYER_DRAWDEBUG);
+ short lthick = gpl->thickness;
+
+ /* apply layer opacity */
+ copy_v3_v3(ink, gpl->color);
+ ink[3] = gpl->opacity;
+
+ /* don't draw layer if hidden */
+ if (gpl->flag & GP_LAYER_HIDE)
+ continue;
+
+ /* get frame to draw */
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra, 0);
+ if (gpf == NULL)
+ 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
+ */
+#define GP_DRAWFLAG_APPLY(condition, draw_flag_value) { \
+ if (condition) dflag |= (draw_flag_value); \
+ else dflag &= ~(draw_flag_value); \
+ } (void)0
+
+ /* xray... */
+ GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_NO_XRAY), GP_DRAWDATA_NO_XRAY);
+
+#undef GP_DRAWFLAG_APPLY
+
+
+ /* draw the strokes already in active frame */
+ gp_draw_strokes(gpd, gpl, gpf, offsx, offsy, winx, winy, dflag, debug, lthick, ink);
+
+ /* Draw verts of selected strokes
+ * - when doing OpenGL renders, we don't want to be showing these, as that ends up flickering
+ * - locked layers can't be edited, so there's no point showing these verts
+ * as they will have no bearings on what gets edited
+ * - only show when in editmode, since operators shouldn't work otherwise
+ * (NOTE: doing it this way means that the toggling editmode shows visible change immediately)
+ */
+ /* XXX: perhaps we don't want to show these when users are drawing... */
+ if ((G.f & G_RENDER_OGL) == 0 &&
+ (gpl->flag & GP_LAYER_LOCKED) == 0 &&
+ (gpd->flag & GP_DATA_STROKE_EDITMODE))
+ {
+ gp_draw_strokes_edit(gpd, gpl, gpf, offsx, offsy, winx, winy, dflag, gpl->flag, alpha);
+ }
+
+ /* Check if may need to draw the active stroke cache, only if this layer is the active layer
+ * that is being edited. (Stroke buffer is currently stored in gp-data)
+ */
+ if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) &&
+ (gpf->flag & GP_FRAME_PAINT))
+ {
+ /* Buffer stroke needs to be drawn with a different linestyle
+ * to help differentiate them from normal strokes.
+ *
+ * It should also be noted that sbuffer contains temporary point types
+ * i.e. tGPspoints NOT bGPDspoints
+ */
+ gp_draw_stroke_buffer(
+ gpd->runtime.sbuffer,
+ gpd->runtime.sbuffer_size, lthick,
+ dflag, gpd->runtime.sbuffer_sflag, ink);
+ }
+ }
+}
+
+/* draw a short status message in the top-right corner */
+static void gp_draw_status_text(const bGPdata *gpd, ARegion *ar)
+{
+ rcti rect;
+
+ /* Cannot draw any status text when drawing OpenGL Renders */
+ if (G.f & G_RENDER_OGL)
+ return;
+
+ /* Get bounds of region - Necessary to avoid problems with region overlap */
+ ED_region_visible_rect(ar, &rect);
+
+ /* for now, this should only be used to indicate when we are in stroke editmode */
+ if (gpd->flag & GP_DATA_STROKE_EDITMODE) {
+ const char *printable = IFACE_("GPencil Stroke Editing");
+ float printable_size[2];
+
+ int font_id = BLF_default();
+
+ BLF_width_and_height(font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
+
+ int xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
+ int yco = (rect.ymax - U.widget_unit);
+
+ /* text label */
+ UI_FontThemeColor(font_id, TH_TEXT_HI);
+#ifdef WITH_INTERNATIONAL
+ BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
+#else
+ BLF_draw_default_ascii(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
+#endif
+
+ /* grease pencil icon... */
+ // XXX: is this too intrusive?
+ GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+
+ xco -= U.widget_unit;
+ yco -= (int)printable_size[1] / 2;
+
+ UI_icon_draw(xco, yco, ICON_GREASEPENCIL);
+
+ GPU_blend(false);
+ }
+}
+
+/* draw grease-pencil datablock */
+static void gp_draw_data(
+ bGPdata *gpd, int offsx, int offsy, int winx, int winy,
+ int cfra, int dflag, float alpha)
+{
+ /* turn on smooth lines (i.e. anti-aliasing) */
+ GPU_line_smooth(true);
+
+ /* turn on alpha-blending */
+ GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+
+ /* draw! */
+ gp_draw_data_layers(gpd, offsx, offsy, winx, winy, cfra, dflag, alpha);
+
+ /* turn off alpha blending, then smooth lines */
+ GPU_blend(false); // alpha blending
+ GPU_line_smooth(false); // smooth lines
+}
+
+/* if we have strokes for scenes (3d view)/clips (movie clip editor)
+ * and objects/tracks, multiple data blocks have to be drawn */
+static void gp_draw_data_all(
+ Scene *scene, bGPdata *gpd, int offsx, int offsy, int winx, int winy,
+ int cfra, int dflag, const char spacetype)
+{
+ bGPdata *gpd_source = NULL;
+ float alpha = 1.0f;
+
+ if (scene) {
+ if (spacetype == SPACE_VIEW3D) {
+ gpd_source = (scene->gpd ? scene->gpd : NULL);
+ }
+ else if (spacetype == SPACE_CLIP && scene->clip) {
+ /* currently drawing only gpencil data from either clip or track, but not both - XXX fix logic behind */
+ gpd_source = (scene->clip->gpd ? scene->clip->gpd : NULL);
+ }
+
+ if (gpd_source) {
+ gp_draw_data(gpd_source, offsx, offsy, winx, winy, cfra, dflag, alpha);
+ }
+ }
+
+ /* scene/clip data has already been drawn, only object/track data is drawn here
+ * if gpd_source == gpd, we don't have any object/track data and we can skip */
+ if (gpd_source == NULL || (gpd_source && gpd_source != gpd)) {
+ gp_draw_data(gpd, offsx, offsy, winx, winy, cfra, dflag, alpha);
+ }
+}
+
+/* ----- 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...
+ * ............................ */
+
+/* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */
+void ED_gpencil_draw_2dimage(const bContext *C)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+
+ int offsx, offsy, sizex, sizey;
+ int dflag = GP_DRAWDATA_NOSTATUS;
+
+ bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX
+ if (gpd == NULL) return;
+
+ /* calculate rect */
+ switch (sa->spacetype) {
+ case SPACE_IMAGE: /* image */
+ case SPACE_CLIP: /* clip */
+ {
+ /* just draw using standard scaling (settings here are currently ignored anyways) */
+ /* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */
+ offsx = 0;
+ offsy = 0;
+ sizex = ar->winx;
+ sizey = ar->winy;
+
+ wmOrtho2(ar->v2d.cur.xmin, ar->v2d.cur.xmax, ar->v2d.cur.ymin, ar->v2d.cur.ymax);
+
+ dflag |= GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_IEDITHACK;
+ break;
+ }
+ case SPACE_SEQ: /* sequence */
+ {
+ /* just draw using standard scaling (settings here are currently ignored anyways) */
+ offsx = 0;
+ offsy = 0;
+ sizex = ar->winx;
+ sizey = ar->winy;
+
+ /* NOTE: I2D was used in 2.4x, but the old settings for that have been deprecated
+ * and everything moved to standard View2d
+ */
+ dflag |= GP_DRAWDATA_ONLYV2D;
+ break;
+ }
+ default: /* for spacetype not yet handled */
+ offsx = 0;
+ offsy = 0;
+ sizex = ar->winx;
+ sizey = ar->winy;
+
+ dflag |= GP_DRAWDATA_ONLYI2D;
+ break;
+ }
+
+ if (ED_screen_animation_playing(wm)) {
+ /* don't show onionskins during animation playback/scrub (i.e. it obscures the poses)
+ * OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes)
+ */
+ dflag |= GP_DRAWDATA_NO_ONIONS;
+ }
+
+ /* draw it! */
+ gp_draw_data_all(scene, gpd, offsx, offsy, sizex, sizey, CFRA, dflag, sa->spacetype);
+}
+
+/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly
+ * Note: this gets called twice - first time with onlyv2d=true to draw 'canvas' strokes,
+ * second time with onlyv2d=false for screen-aligned strokes */
+void ED_gpencil_draw_view2d(const bContext *C, bool onlyv2d)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ int dflag = 0;
+
+ /* check that we have grease-pencil stuff to draw */
+ if (sa == NULL) return;
+ bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX
+ if (gpd == NULL) return;
+
+ /* special hack for Image Editor */
+ /* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */
+ if (ELEM(sa->spacetype, SPACE_IMAGE, SPACE_CLIP))
+ dflag |= GP_DRAWDATA_IEDITHACK;
+
+ /* draw it! */
+ if (onlyv2d) dflag |= (GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_NOSTATUS);
+ if (ED_screen_animation_playing(wm)) dflag |= GP_DRAWDATA_NO_ONIONS;
+
+ gp_draw_data_all(scene, gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag, sa->spacetype);
+
+ /* draw status text (if in screen/pixel-space) */
+ if (!onlyv2d) {
+ gp_draw_status_text(gpd, ar);
+ }
+}
+
+
+/* draw annotations sketches to specified 3d-view assuming that matrices are already set correctly
+ * Note: this gets called twice - first time with only3d=true to draw 3d-strokes,
+ * second time with only3d=false for screen-aligned strokes */
+void ED_gpencil_draw_view3d_annotations(
+ Scene *scene, struct Depsgraph *depsgraph,
+ View3D *v3d, ARegion *ar,
+ bool only3d)
+{
+ int dflag = 0;
+ RegionView3D *rv3d = ar->regiondata;
+ int offsx, offsy, winx, winy;
+
+ /* check that we have grease-pencil stuff to draw */
+ /* XXX: Hardcoded reference here may get out of sync if we change how we fetch annotation data */
+ bGPdata *gpd = scene->gpd;
+ if (gpd == NULL) return;
+
+ /* when rendering to the offscreen buffer we don't want to
+ * deal with the camera border, otherwise map the coords to the camera border. */
+ if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) {
+ rctf rectf;
+ ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &rectf, true); /* no shift */
+
+ offsx = round_fl_to_int(rectf.xmin);
+ offsy = round_fl_to_int(rectf.ymin);
+ winx = round_fl_to_int(rectf.xmax - rectf.xmin);
+ winy = round_fl_to_int(rectf.ymax - rectf.ymin);
+ }
+ else {
+ offsx = 0;
+ offsy = 0;
+ winx = ar->winx;
+ winy = ar->winy;
+ }
+
+ /* set flags */
+ if (only3d) {
+ /* 3D strokes/3D space:
+ * - only 3D space points
+ * - don't status text either (as it's the wrong space)
+ */
+ dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS);
+ }
+
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
+ /* don't draw status text when "only render" flag is set */
+ dflag |= GP_DRAWDATA_NOSTATUS;
+ }
+
+ /* draw it! */
+ gp_draw_data_all(scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype);
+}
+
+#if 0 // XXX: Reinstate, after renaming the functions
+
+void ED_gpencil_draw_ex(Scene *scene, bGPdata *gpd, int winx, int winy, const int cfra, const char spacetype)
+{
+ int dflag = GP_DRAWDATA_NOSTATUS | GP_DRAWDATA_ONLYV2D;
+
+ gp_draw_data_all(scene, gpd, 0, 0, winx, winy, cfra, dflag, spacetype);
+}
+
+#endif
+
+/* ************************************************** */
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
new file mode 100644
index 00000000000..b551f3d630b
--- /dev/null
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -0,0 +1,2393 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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/2018, Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/gpencil/annotate_paint.c
+ * \ingroup edgpencil
+ */
+
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_math_geom.h"
+
+#include "BLT_translation.h"
+
+#include "PIL_time.h"
+
+#include "BKE_colortools.h"
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_gpencil.h"
+#include "BKE_main.h"
+#include "BKE_report.h"
+#include "BKE_screen.h"
+#include "BKE_tracking.h"
+
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "UI_view2d.h"
+
+#include "ED_gpencil.h"
+#include "ED_screen.h"
+#include "ED_view3d.h"
+#include "ED_clip.h"
+
+#include "BIF_glutil.h"
+
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_state.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "DEG_depsgraph.h"
+
+#include "gpencil_intern.h"
+
+/* ******************************************* */
+/* 'Globals' and Defines */
+
+/* values for tGPsdata->status */
+typedef enum eGPencil_PaintStatus {
+ GP_STATUS_IDLING = 0, /* stroke isn't in progress yet */
+ GP_STATUS_PAINTING, /* a stroke is in progress */
+ GP_STATUS_ERROR, /* something wasn't correctly set up */
+ GP_STATUS_DONE /* painting done */
+} eGPencil_PaintStatus;
+
+/* Return flags for adding points to stroke buffer */
+typedef enum eGP_StrokeAdd_Result {
+ GP_STROKEADD_INVALID = -2, /* error occurred - insufficient info to do so */
+ GP_STROKEADD_OVERFLOW = -1, /* error occurred - cannot fit any more points */
+ GP_STROKEADD_NORMAL, /* point was successfully added */
+ GP_STROKEADD_FULL /* cannot add any more points to buffer */
+} eGP_StrokeAdd_Result;
+
+/* Runtime flags */
+typedef enum eGPencil_PaintFlags {
+ GP_PAINTFLAG_FIRSTRUN = (1 << 0), /* operator just started */
+ GP_PAINTFLAG_STROKEADDED = (1 << 1),
+ GP_PAINTFLAG_V3D_ERASER_DEPTH = (1 << 2),
+ GP_PAINTFLAG_SELECTMASK = (1 << 3),
+} eGPencil_PaintFlags;
+
+
+/* Temporary 'Stroke' Operation data
+ * "p" = op->customdata
+ */
+typedef struct tGPsdata {
+ Main *bmain;
+ Scene *scene; /* current scene from context */
+ struct Depsgraph *depsgraph;
+
+ wmWindow *win; /* window where painting originated */
+ ScrArea *sa; /* area where painting originated */
+ ARegion *ar; /* region where painting originated */
+ View2D *v2d; /* needed for GP_STROKE_2DSPACE */
+ rctf *subrect; /* for using the camera rect within the 3d view */
+ rctf subrect_data;
+
+ GP_SpaceConversion gsc; /* settings to pass to gp_points_to_xy() */
+
+ PointerRNA ownerPtr; /* pointer to owner of gp-datablock */
+ bGPdata *gpd; /* gp-datablock layer comes from */
+ bGPDlayer *gpl; /* layer we're working on */
+ bGPDframe *gpf; /* frame we're working on */
+
+ char *align_flag; /* projection-mode flags (toolsettings - eGPencil_Placement_Flags) */
+
+ eGPencil_PaintStatus status; /* current status of painting */
+ eGPencil_PaintModes paintmode; /* mode for painting */
+ eGPencil_PaintFlags flags; /* flags that can get set during runtime (eGPencil_PaintFlags) */
+
+ short radius; /* radius of influence for eraser */
+
+ int mval[2]; /* current mouse-position */
+ int mvalo[2]; /* previous recorded mouse-position */
+
+ float pressure; /* current stylus pressure */
+ float opressure; /* previous stylus pressure */
+
+ /* These need to be doubles, as (at least under unix) they are in seconds since epoch,
+ * float (and its 7 digits precision) is definitively not enough here!
+ * double, with its 15 digits precision, ensures us millisecond precision for a few centuries at least.
+ */
+ double inittime; /* Used when converting to path */
+ double curtime; /* Used when converting to path */
+ double ocurtime; /* Used when converting to path */
+
+ float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space
+ * to region space */
+ float mat[4][4];
+
+ float custom_color[4]; /* custom color - hack for enforcing a particular color for track/mask editing */
+
+ void *erasercursor; /* radial cursor data for drawing eraser */
+
+ short straight[2]; /* 1: line horizontal, 2: line vertical, other: not defined, second element position */
+ int lock_axis; /* lock drawing to one axis */
+
+ short keymodifier; /* key used for invoking the operator */
+} tGPsdata;
+
+/* ------ */
+
+/* Macros for accessing sensitivity thresholds... */
+/* minimum number of pixels mouse should move before new point created */
+#define MIN_MANHATTEN_PX (U.gp_manhattendist)
+/* 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)
+{
+ return (p->gpf && p->gpf->strokes.last && p->flags & GP_PAINTFLAG_STROKEADDED);
+}
+
+static void gp_stroke_added_enable(tGPsdata *p)
+{
+ BLI_assert(p->gpf->strokes.last != NULL);
+ p->flags |= GP_PAINTFLAG_STROKEADDED;
+}
+
+/* ------ */
+/* Forward defines for some functions... */
+
+static void gp_session_validatebuffer(tGPsdata *p);
+
+/* ******************************************* */
+/* Context Wrangling... */
+
+/* check if context is suitable for drawing */
+static bool gpencil_draw_poll(bContext *C)
+{
+ if (ED_operator_regionactive(C)) {
+ /* check if current context can support GPencil data */
+ if (ED_gpencil_data_get_pointers(C, NULL) != NULL) {
+ /* check if Grease Pencil isn't already running */
+ if (ED_gpencil_session_active() == 0)
+ return 1;
+ else
+ CTX_wm_operator_poll_msg_set(C, "Annotation operator is already active");
+ }
+ else {
+ CTX_wm_operator_poll_msg_set(C, "Failed to find Grease Pencil data to draw into");
+ }
+ }
+ else {
+ CTX_wm_operator_poll_msg_set(C, "Active region not set");
+ }
+
+ return 0;
+}
+
+/* check if projecting strokes into 3d-geometry in the 3D-View */
+static bool gpencil_project_check(tGPsdata *p)
+{
+ bGPdata *gpd = p->gpd;
+ return ((gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) && (*p->align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE)));
+}
+
+/* ******************************************* */
+/* Calculations/Conversions */
+
+/* Utilities --------------------------------- */
+
+/* get the reference point for stroke-point conversions */
+static void gp_get_3d_reference(tGPsdata *p, float vec[3])
+{
+ View3D *v3d = p->sa->spacedata.first;
+ const float *fp = ED_view3d_cursor3d_get(p->scene, v3d)->location;
+
+ /* use 3D-cursor */
+ copy_v3_v3(vec, fp);
+}
+
+/* Stroke Editing ---------------------------- */
+
+/* check if the current mouse position is suitable for adding a new point */
+static bool gp_stroke_filtermval(tGPsdata *p, const int mval[2], int pmval[2])
+{
+ int dx = abs(mval[0] - pmval[0]);
+ int dy = abs(mval[1] - pmval[1]);
+
+ /* if buffer is empty, just let this go through (i.e. so that dots will work) */
+ if (p->gpd->runtime.sbuffer_size == 0)
+ return true;
+
+ /* check if mouse moved at least certain distance on both axes (best case)
+ * - aims to eliminate some jitter-noise from input when trying to draw straight lines freehand
+ */
+ else if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX))
+ return true;
+
+ /* check if the distance since the last point is significant enough
+ * - prevents points being added too densely
+ * - distance here doesn't use sqrt to prevent slowness... we should still be safe from overflows though
+ */
+ else if ((dx * dx + dy * dy) > MIN_EUCLIDEAN_PX * MIN_EUCLIDEAN_PX)
+ return true;
+
+ /* mouse 'didn't move' */
+ else
+ return false;
+}
+
+/* reproject the points of the stroke to a plane locked to axis to avoid stroke offset */
+static void gp_project_points_to_plane(RegionView3D *rv3d, bGPDstroke *gps, const float origin[3], const int axis)
+{
+ float plane_normal[3];
+ float vn[3];
+
+ float ray[3];
+ float rpoint[3];
+
+ /* normal vector for a plane locked to axis */
+ zero_v3(plane_normal);
+ plane_normal[axis] = 1.0f;
+
+ /* Reproject the points in the plane */
+ for (int i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+
+ /* get a vector from the point with the current view direction of the viewport */
+ ED_view3d_global_to_vector(rv3d, &pt->x, vn);
+
+ /* calculate line extrem point to create a ray that cross the plane */
+ mul_v3_fl(vn, -50.0f);
+ add_v3_v3v3(ray, &pt->x, vn);
+
+ /* if the line never intersect, the point is not changed */
+ if (isect_line_plane_v3(rpoint, &pt->x, ray, origin, plane_normal)) {
+ copy_v3_v3(&pt->x, rpoint);
+ }
+ }
+}
+
+/* reproject stroke to plane locked to axis in 3d cursor location */
+static void gp_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
+{
+ bGPdata *gpd = p->gpd;
+ float origin[3];
+ float cursor[3];
+ RegionView3D *rv3d = p->ar->regiondata;
+
+ /* verify the stroke mode is CURSOR 3d space mode */
+ if ((gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) == 0) {
+ return;
+ }
+ if ((*p->align_flag & GP_PROJECT_VIEWSPACE) == 0) {
+ return;
+ }
+ if ((*p->align_flag & GP_PROJECT_DEPTH_VIEW) || (*p->align_flag & GP_PROJECT_DEPTH_STROKE)) {
+ return;
+ }
+
+ /* get 3d cursor and set origin for locked axis only. Uses axis-1 because the enum for XYZ start with 1 */
+ gp_get_3d_reference(p, cursor);
+ zero_v3(origin);
+ origin[p->lock_axis - 1] = cursor[p->lock_axis - 1];
+
+ gp_project_points_to_plane(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 int mval[2], float out[3], float *depth)
+{
+ bGPdata *gpd = p->gpd;
+
+ /* in 3d-space - pt->x/y/z are 3 side-by-side floats */
+ if (gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) {
+ if (gpencil_project_check(p) && (ED_view3d_autodist_simple(p->ar, mval, out, 0, depth))) {
+ /* projecting onto 3D-Geometry
+ * - nothing more needs to be done here, since view_autodist_simple() has already done it
+ */
+ }
+ else {
+ float mval_prj[2];
+ float rvec[3], dvec[3];
+ float mval_f[2] = {UNPACK2(mval)};
+ float zfac;
+
+ /* Current method just converts each point in screen-coordinates to
+ * 3D-coordinates using the 3D-cursor as reference. In general, this
+ * works OK, but it could of course be improved.
+ *
+ * TODO:
+ * - investigate using nearest point(s) on a previous stroke as
+ * reference point instead or as offset, for easier stroke matching
+ */
+
+ gp_get_3d_reference(p, rvec);
+ zfac = ED_view3d_calc_zfac(p->ar->regiondata, rvec, NULL);
+
+ if (ED_view3d_project_float_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ sub_v2_v2v2(mval_f, mval_prj, mval_f);
+ ED_view3d_win_to_delta(p->ar, mval_f, dvec, zfac);
+ sub_v3_v3v3(out, rvec, dvec);
+ }
+ else {
+ zero_v3(out);
+ }
+ }
+ }
+
+ /* 2d - on 'canvas' (assume that p->v2d is set) */
+ else if ((gpd->runtime.sbuffer_sflag & GP_STROKE_2DSPACE) && (p->v2d)) {
+ UI_view2d_region_to_view(p->v2d, mval[0], mval[1], &out[0], &out[1]);
+ mul_v3_m4v3(out, p->imat, out);
+ }
+
+ /* 2d - relative to screen (viewport area) */
+ else {
+ if (p->subrect == NULL) { /* normal 3D view */
+ out[0] = (float)(mval[0]) / (float)(p->ar->winx) * 100;
+ out[1] = (float)(mval[1]) / (float)(p->ar->winy) * 100;
+ }
+ else { /* camera view, use subrect */
+ out[0] = ((mval[0] - p->subrect->xmin) / BLI_rctf_size_x(p->subrect)) * 100;
+ out[1] = ((mval[1] - p->subrect->ymin) / BLI_rctf_size_y(p->subrect)) * 100;
+ }
+ }
+}
+
+/* add current stroke-point to buffer (returns whether point was successfully added) */
+static short gp_stroke_addpoint(
+ tGPsdata *p, const int mval[2], float pressure, double curtime)
+{
+ bGPdata *gpd = p->gpd;
+ tGPspoint *pt;
+ ToolSettings *ts = p->scene->toolsettings;
+
+ /* check painting mode */
+ if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
+ /* straight lines only - i.e. only store start and end point in buffer */
+ if (gpd->runtime.sbuffer_size == 0) {
+ /* first point in buffer (start point) */
+ pt = (tGPspoint *)(gpd->runtime.sbuffer);
+
+ /* store settings */
+ copy_v2_v2_int(&pt->x, mval);
+ pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */
+ pt->strength = 1.0f;
+ pt->time = (float)(curtime - p->inittime);
+
+ /* increment buffer size */
+ gpd->runtime.sbuffer_size++;
+ }
+ else {
+ /* just reset the endpoint to the latest value
+ * - assume that pointers for this are always valid...
+ */
+ pt = ((tGPspoint *)(gpd->runtime.sbuffer) + 1);
+
+ /* store settings */
+ copy_v2_v2_int(&pt->x, mval);
+ pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */
+ pt->strength = 1.0f;
+ pt->time = (float)(curtime - p->inittime);
+
+ /* now the buffer has 2 points (and shouldn't be allowed to get any larger) */
+ gpd->runtime.sbuffer_size = 2;
+ }
+
+ /* can keep carrying on this way :) */
+ return GP_STROKEADD_NORMAL;
+ }
+ else if (p->paintmode == GP_PAINTMODE_DRAW) { /* normal drawing */
+ /* check if still room in buffer */
+ if (gpd->runtime.sbuffer_size >= GP_STROKE_BUFFER_MAX)
+ return GP_STROKEADD_OVERFLOW;
+
+ /* get pointer to destination point */
+ pt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_size);
+
+ /* store settings */
+ copy_v2_v2_int(&pt->x, mval);
+ pt->pressure = pressure;
+ pt->strength = 1.0f; /* unused for annotations, but initialise for easier conversions to GP Object */
+
+ /* point time */
+ pt->time = (float)(curtime - p->inittime);
+
+ /* increment counters */
+ gpd->runtime.sbuffer_size++;
+
+ /* check if another operation can still occur */
+ if (gpd->runtime.sbuffer_size == GP_STROKE_BUFFER_MAX)
+ return GP_STROKEADD_FULL;
+ else
+ return GP_STROKEADD_NORMAL;
+ }
+ else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
+ /* get pointer to destination point */
+ pt = (tGPspoint *)(gpd->runtime.sbuffer);
+
+ /* store settings */
+ copy_v2_v2_int(&pt->x, mval);
+ pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */
+ pt->strength = 1.0f;
+ pt->time = (float)(curtime - p->inittime);
+
+ /* if there's stroke for this poly line session add (or replace last) point
+ * to stroke. This allows to draw lines more interactively (see new segment
+ * during mouse slide, e.g.)
+ */
+ if (gp_stroke_added_check(p)) {
+ bGPDstroke *gps = p->gpf->strokes.last;
+ bGPDspoint *pts;
+
+ /* first time point is adding to temporary buffer -- need to allocate new point in stroke */
+ if (gpd->runtime.sbuffer_size == 0) {
+ gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1));
+ gps->totpoints++;
+ }
+
+ pts = &gps->points[gps->totpoints - 1];
+
+ /* special case for poly lines: normally,
+ * depth is needed only when creating new stroke from buffer,
+ * but poly lines are converting to stroke instantly,
+ * so initialize depth buffer before converting coordinates
+ */
+ if (gpencil_project_check(p)) {
+ View3D *v3d = p->sa->spacedata.first;
+
+ view3d_region_operator_needs_opengl(p->win, p->ar);
+ ED_view3d_autodist_init(
+ p->depsgraph, p->ar, v3d, (ts->annotate_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
+ }
+
+ /* convert screen-coordinates to appropriate coordinates (and store them) */
+ gp_stroke_convertcoords(p, &pt->x, &pts->x, NULL);
+ /* if axis locked, reproject to plane locked (only in 3d space) */
+ if (p->lock_axis > GP_LOCKAXIS_NONE) {
+ gp_reproject_toplane(p, gps);
+ }
+
+ /* copy pressure and time */
+ pts->pressure = pt->pressure;
+ pts->strength = pt->strength;
+ pts->time = pt->time;
+
+ /* force fill recalc */
+ gps->flag |= GP_STROKE_RECALC_CACHES;
+ }
+
+ /* increment counters */
+ if (gpd->runtime.sbuffer_size == 0)
+ gpd->runtime.sbuffer_size++;
+
+ return GP_STROKEADD_NORMAL;
+ }
+
+ /* return invalid state for now... */
+ return GP_STROKEADD_INVALID;
+}
+
+/* simplify a stroke (in buffer) before storing it
+ * - applies a reverse Chaikin filter
+ * - code adapted from etch-a-ton branch
+ */
+static void gp_stroke_simplify(tGPsdata *p)
+{
+ bGPdata *gpd = p->gpd;
+ tGPspoint *old_points = (tGPspoint *)gpd->runtime.sbuffer;
+ short num_points = gpd->runtime.sbuffer_size;
+ short flag = gpd->runtime.sbuffer_sflag;
+ short i, j;
+
+ /* only simplify if simplification is enabled, and we're not doing a straight line */
+ if (!(U.gp_settings & GP_PAINT_DOSIMPLIFY) || (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT))
+ return;
+
+ /* don't simplify if less than 4 points in buffer */
+ if ((num_points <= 4) || (old_points == NULL))
+ return;
+
+ /* clear buffer (but don't free mem yet) so that we can write to it
+ * - firstly set sbuffer to NULL, so a new one is allocated
+ * - secondly, reset flag after, as it gets cleared auto
+ */
+ gpd->runtime.sbuffer = NULL;
+ gp_session_validatebuffer(p);
+ gpd->runtime.sbuffer_sflag = flag;
+
+/* macro used in loop to get position of new point
+ * - used due to the mixture of datatypes in use here
+ */
+#define GP_SIMPLIFY_AVPOINT(offs, sfac) \
+ { \
+ co[0] += (float)(old_points[offs].x * sfac); \
+ co[1] += (float)(old_points[offs].y * sfac); \
+ pressure += old_points[offs].pressure * sfac; \
+ time += old_points[offs].time * sfac; \
+ } (void)0
+
+ /* XXX Here too, do not lose start and end points! */
+ gp_stroke_addpoint(p, &old_points->x, old_points->pressure, p->inittime + (double)old_points->time);
+ for (i = 0, j = 0; i < num_points; i++) {
+ if (i - j == 3) {
+ float co[2], pressure, time;
+ int mco[2];
+
+ /* initialize values */
+ co[0] = 0.0f;
+ co[1] = 0.0f;
+ pressure = 0.0f;
+ time = 0.0f;
+
+ /* using macro, calculate new point */
+ GP_SIMPLIFY_AVPOINT(j, -0.25f);
+ GP_SIMPLIFY_AVPOINT(j + 1, 0.75f);
+ GP_SIMPLIFY_AVPOINT(j + 2, 0.75f);
+ GP_SIMPLIFY_AVPOINT(j + 3, -0.25f);
+
+ /* set values for adding */
+ mco[0] = (int)co[0];
+ mco[1] = (int)co[1];
+
+ /* ignore return values on this... assume to be ok for now */
+ gp_stroke_addpoint(p, mco, pressure, p->inittime + (double)time);
+
+ j += 2;
+ }
+ }
+ gp_stroke_addpoint(p, &old_points[num_points - 1].x, old_points[num_points - 1].pressure,
+ p->inittime + (double)old_points[num_points - 1].time);
+
+ /* free old buffer */
+ MEM_freeN(old_points);
+}
+
+/* make a new stroke from the buffer data */
+static void gp_stroke_newfrombuffer(tGPsdata *p)
+{
+ bGPdata *gpd = p->gpd;
+ bGPDlayer *gpl = p->gpl;
+ bGPDstroke *gps;
+ bGPDspoint *pt;
+ tGPspoint *ptc;
+ ToolSettings *ts = p->scene->toolsettings;
+
+ int i, totelem;
+ /* since strokes are so fine, when using their depth we need a margin otherwise they might get missed */
+ int depth_margin = (ts->annotate_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 4 : 0;
+
+ /* get total number of points to allocate space for
+ * - drawing straight-lines only requires the endpoints
+ */
+ if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT)
+ totelem = (gpd->runtime.sbuffer_size >= 2) ? 2 : gpd->runtime.sbuffer_size;
+ else
+ totelem = gpd->runtime.sbuffer_size;
+
+ /* exit with error if no valid points from this stroke */
+ if (totelem == 0) {
+ if (G.debug & G_DEBUG)
+ printf("Error: No valid points in stroke buffer to convert (tot=%d)\n", gpd->runtime.sbuffer_size);
+ return;
+ }
+
+ /* special case for poly line -- for already added stroke during session
+ * coordinates are getting added to stroke immediately to allow more
+ * interactive behavior
+ */
+ if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
+ if (gp_stroke_added_check(p)) {
+ return;
+ }
+ }
+
+ /* allocate memory for a new stroke */
+ gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
+
+ /* copy appropriate settings for stroke */
+ gps->totpoints = totelem;
+ gps->thickness = gpl->thickness;
+ gps->flag = gpd->runtime.sbuffer_sflag;
+ gps->inittime = p->inittime;
+
+ /* enable recalculation flag by default (only used if hq fill) */
+ gps->flag |= GP_STROKE_RECALC_CACHES;
+
+ /* allocate enough memory for a continuous array for storage points */
+ gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ gps->tot_triangles = 0;
+
+ /* set pointer to first non-initialized point */
+ pt = gps->points + (gps->totpoints - totelem);
+
+ /* copy points from the buffer to the stroke */
+ if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
+ /* straight lines only -> only endpoints */
+ {
+ /* first point */
+ ptc = gpd->runtime.sbuffer;
+
+ /* convert screen-coordinates to appropriate coordinates (and store them) */
+ gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
+ /* if axis locked, reproject to plane locked (only in 3d space) */
+ if (p->lock_axis > GP_LOCKAXIS_NONE) {
+ gp_reproject_toplane(p, gps);
+ }
+ /* copy pressure and time */
+ pt->pressure = ptc->pressure;
+ pt->strength = ptc->strength;
+ CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
+ pt->time = ptc->time;
+
+ pt++;
+ }
+
+ if (totelem == 2) {
+ /* last point if applicable */
+ ptc = ((tGPspoint *)gpd->runtime.sbuffer) + (gpd->runtime.sbuffer_size - 1);
+
+ /* convert screen-coordinates to appropriate coordinates (and store them) */
+ gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
+ /* if axis locked, reproject to plane locked (only in 3d space) */
+ if (p->lock_axis > GP_LOCKAXIS_NONE) {
+ gp_reproject_toplane(p, gps);
+ }
+
+ /* copy pressure and time */
+ pt->pressure = ptc->pressure;
+ pt->strength = ptc->strength;
+ CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
+ pt->time = ptc->time;
+ }
+ }
+ else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
+ /* first point */
+ ptc = gpd->runtime.sbuffer;
+
+ /* convert screen-coordinates to appropriate coordinates (and store them) */
+ gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
+ /* if axis locked, reproject to plane locked (only in 3d space) */
+ if (p->lock_axis > GP_LOCKAXIS_NONE) {
+ gp_reproject_toplane(p, gps);
+ }
+ /* copy pressure and time */
+ pt->pressure = ptc->pressure;
+ pt->strength = ptc->strength;
+ pt->time = ptc->time;
+ }
+ else {
+ float *depth_arr = NULL;
+
+ /* get an array of depths, far depths are blended */
+ if (gpencil_project_check(p)) {
+ int mval[2], mval_prev[2] = { 0 };
+ int interp_depth = 0;
+ int found_depth = 0;
+
+ depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_size, "depth_points");
+
+ for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size; i++, ptc++, pt++) {
+ copy_v2_v2_int(mval, &ptc->x);
+
+ if ((ED_view3d_autodist_depth(p->ar, mval, depth_margin, depth_arr + i) == 0) &&
+ (i && (ED_view3d_autodist_depth_seg(p->ar, mval, mval_prev, depth_margin + 1, depth_arr + i) == 0)))
+ {
+ interp_depth = true;
+ }
+ else {
+ found_depth = true;
+ }
+
+ copy_v2_v2_int(mval_prev, mval);
+ }
+
+ if (found_depth == false) {
+ /* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */
+ for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--)
+ depth_arr[i] = 0.9999f;
+ }
+ else {
+ if (ts->annotate_v3d_align & GP_PROJECT_DEPTH_STROKE_ENDPOINTS) {
+ /* remove all info between the valid endpoints */
+ int first_valid = 0;
+ int last_valid = 0;
+
+ for (i = 0; i < gpd->runtime.sbuffer_size; i++) {
+ if (depth_arr[i] != FLT_MAX)
+ break;
+ }
+ first_valid = i;
+
+ for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) {
+ if (depth_arr[i] != FLT_MAX)
+ break;
+ }
+ last_valid = i;
+
+ /* invalidate non-endpoints, so only blend between first and last */
+ for (i = first_valid + 1; i < last_valid; i++)
+ depth_arr[i] = FLT_MAX;
+
+ interp_depth = true;
+ }
+
+ if (interp_depth) {
+ interp_sparse_array(depth_arr, gpd->runtime.sbuffer_size, FLT_MAX);
+ }
+ }
+ }
+
+
+ pt = gps->points;
+
+ /* convert all points (normal behavior) */
+ for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size && 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);
+
+ /* copy pressure and time */
+ pt->pressure = ptc->pressure;
+ pt->strength = ptc->strength;
+ CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
+ pt->time = ptc->time;
+ }
+
+ /* if axis locked, reproject to plane locked (only in 3d space) */
+ if (p->lock_axis > GP_LOCKAXIS_NONE) {
+ gp_reproject_toplane(p, gps);
+ }
+
+ if (depth_arr)
+ MEM_freeN(depth_arr);
+ }
+
+ /* add stroke to frame */
+ BLI_addtail(&p->gpf->strokes, gps);
+ gp_stroke_added_enable(p);
+}
+
+/* --- 'Eraser' for 'Paint' Tool ------ */
+
+/* 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(bGPdata *UNUSED(gpd), bGPDframe *gpf, bGPDstroke *gps)
+{
+ if (gps->points) {
+ MEM_freeN(gps->points);
+ }
+
+ if (gps->dvert) {
+ BKE_gpencil_free_stroke_weights(gps);
+ MEM_freeN(gps->dvert);
+ }
+
+ if (gps->triangles) {
+ MEM_freeN(gps->triangles);
+ }
+
+ BLI_freelinkN(&gpf->strokes, gps);
+}
+
+
+/* which which point is infront (result should only be used for comparison) */
+static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
+{
+ if (rv3d->is_persp) {
+ return ED_view3d_calc_zfac(rv3d, co, NULL);
+ }
+ else {
+ return -dot_v3v3(rv3d->viewinv[2], co);
+ }
+}
+
+/* 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)
+{
+ if ((p->sa->spacetype == SPACE_VIEW3D) &&
+ (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH))
+ {
+ RegionView3D *rv3d = p->ar->regiondata;
+ const int mval[2] = {x, y};
+ float mval_3d[3];
+
+ if (ED_view3d_autodist_simple(p->ar, mval, mval_3d, 0, NULL)) {
+ const float depth_mval = view3d_point_depth(rv3d, mval_3d);
+ const float depth_pt = view3d_point_depth(rv3d, &pt->x);
+
+ if (depth_pt > depth_mval) {
+ return true;
+ }
+ }
+ }
+ 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 int mval[2], const int mvalo[2],
+ const int radius, const rcti *rect)
+{
+ bGPDspoint *pt1, *pt2;
+ int pc1[2] = {0};
+ int pc2[2] = {0};
+ int i;
+
+ if (gps->totpoints == 0) {
+ /* just free stroke */
+ gp_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)) {
+ gp_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, pc1) <= radius) {
+ /* free stroke */
+ gp_free_stroke(p->gpd, gpf, gps);
+ }
+ }
+ }
+ }
+ else {
+ /* Perform culling? */
+ bool do_cull = false;
+
+ /* Clear Tags
+ *
+ * Note: It's better this way, as we are sure that
+ * we don't miss anything, though things will be
+ * slightly slower as a result
+ */
+ for (i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+ pt->flag &= ~GP_SPOINT_TAG;
+ }
+
+ /* First Pass: Loop over the points in the stroke
+ * 1) Thin out parts of the stroke under the brush
+ * 2) Tag "too thin" parts for removal (in second pass)
+ */
+ for (i = 0; (i + 1) < gps->totpoints; i++) {
+ /* get points to work with */
+ pt1 = gps->points + i;
+ pt2 = gps->points + i + 1;
+
+ /* only process if it hasn't been masked out... */
+ if ((p->flags & GP_PAINTFLAG_SELECTMASK) && !(gps->points->flag & GP_SPOINT_SELECT))
+ 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]);
+
+ /* 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])) ||
+ ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1])))
+ {
+ /* 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, mvalo, 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))
+ {
+ /* Edge is affected - Check individual points now */
+ if (len_v2v2_int(mval, pc1) <= radius) {
+ pt1->flag |= GP_SPOINT_TAG;
+ }
+ if (len_v2v2_int(mval, pc2) <= radius) {
+ pt2->flag |= GP_SPOINT_TAG;
+ }
+ do_cull = true;
+ }
+ }
+ }
+ }
+
+ /* Second Pass: Remove any points that are tagged */
+ if (do_cull) {
+ gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false);
+ }
+ }
+}
+
+/* erase strokes which fall under the eraser strokes */
+static void gp_stroke_doeraser(tGPsdata *p)
+{
+ bGPDframe *gpf = p->gpf;
+ bGPDstroke *gps, *gpn;
+ rcti rect;
+
+ /* rect is rectangle of eraser */
+ rect.xmin = p->mval[0] - p->radius;
+ rect.ymin = p->mval[1] - p->radius;
+ rect.xmax = p->mval[0] + p->radius;
+ rect.ymax = p->mval[1] + p->radius;
+
+ if (p->sa->spacetype == SPACE_VIEW3D) {
+ if (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH) {
+ View3D *v3d = p->sa->spacedata.first;
+ view3d_region_operator_needs_opengl(p->win, p->ar);
+ ED_view3d_autodist_init(p->depsgraph, p->ar, v3d, 0);
+ }
+ }
+
+ /* loop over strokes of active layer only (session init already took care of ensuring validity),
+ * checking segments for intersections to remove
+ */
+ for (gps = gpf->strokes.first; gps; gps = gpn) {
+ gpn = gps->next;
+ /* Not all strokes in the datablock may be valid in the current editor/context
+ * (e.g. 2D space strokes in the 3D view, if the same datablock is shared)
+ */
+ if (ED_gpencil_stroke_can_use_direct(p->sa, gps)) {
+ gp_stroke_eraser_dostroke(p, gpf, gps, p->mval, p->mvalo, p->radius, &rect);
+ }
+ }
+}
+
+/* ******************************************* */
+/* Sketching Operator */
+
+/* clear the session buffers (call this before AND after a paint operation) */
+static void gp_session_validatebuffer(tGPsdata *p)
+{
+ bGPdata *gpd = p->gpd;
+
+ /* clear memory of buffer (or allocate it if starting a new session) */
+ if (gpd->runtime.sbuffer) {
+ /* printf("\t\tGP - reset sbuffer\n"); */
+ memset(gpd->runtime.sbuffer, 0, sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX);
+ }
+ else {
+ /* printf("\t\tGP - allocate sbuffer\n"); */
+ gpd->runtime.sbuffer = MEM_callocN(sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
+ }
+
+ /* reset indices */
+ gpd->runtime.sbuffer_size = 0;
+
+ /* reset flags */
+ gpd->runtime.sbuffer_sflag = 0;
+
+ /* reset inittime */
+ p->inittime = 0.0;
+}
+
+/* (re)init new painting data */
+static bool gp_session_initdata(bContext *C, tGPsdata *p)
+{
+ Main *bmain = CTX_data_main(C);
+ bGPdata **gpd_ptr = NULL;
+ ScrArea *curarea = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+
+ /* make sure the active view (at the starting time) is a 3d-view */
+ if (curarea == NULL) {
+ p->status = GP_STATUS_ERROR;
+ if (G.debug & G_DEBUG)
+ printf("Error: No active view for painting\n");
+ return 0;
+ }
+
+ /* pass on current scene and window */
+ p->bmain = CTX_data_main(C);
+ p->scene = CTX_data_scene(C);
+ p->depsgraph = CTX_data_depsgraph(C);
+ p->win = CTX_wm_window(C);
+
+ unit_m4(p->imat);
+ unit_m4(p->mat);
+
+ switch (curarea->spacetype) {
+ /* supported views first */
+ case SPACE_VIEW3D:
+ {
+ /* View3D *v3d = curarea->spacedata.first; */
+ /* RegionView3D *rv3d = ar->regiondata; */
+
+ /* set current area
+ * - must verify that region data is 3D-view (and not something else)
+ */
+ /* CAUTION: If this is the "toolbar", then this will change on the first stroke */
+ p->sa = curarea;
+ p->ar = ar;
+ p->align_flag = &ts->annotate_v3d_align;
+
+ if (ar->regiondata == NULL) {
+ p->status = GP_STATUS_ERROR;
+ if (G.debug & G_DEBUG)
+ printf("Error: 3D-View active region doesn't have any region data, so cannot be drawable\n");
+ return 0;
+ }
+ break;
+ }
+ case SPACE_NODE:
+ {
+ /* SpaceNode *snode = curarea->spacedata.first; */
+
+ /* set current area */
+ p->sa = curarea;
+ p->ar = ar;
+ p->v2d = &ar->v2d;
+ p->align_flag = &ts->gpencil_v2d_align;
+ break;
+ }
+ case SPACE_SEQ:
+ {
+ SpaceSeq *sseq = curarea->spacedata.first;
+
+ /* set current area */
+ p->sa = curarea;
+ p->ar = ar;
+ p->v2d = &ar->v2d;
+ p->align_flag = &ts->gpencil_seq_align;
+
+ /* check that gpencil data is allowed to be drawn */
+ if (sseq->mainb == SEQ_DRAW_SEQUENCE) {
+ p->status = GP_STATUS_ERROR;
+ if (G.debug & G_DEBUG)
+ printf("Error: In active view (sequencer), active mode doesn't support Grease Pencil\n");
+ return 0;
+ }
+ break;
+ }
+ case SPACE_IMAGE:
+ {
+ /* SpaceImage *sima = curarea->spacedata.first; */
+
+ /* set the current area */
+ p->sa = curarea;
+ p->ar = ar;
+ p->v2d = &ar->v2d;
+ p->align_flag = &ts->gpencil_ima_align;
+ break;
+ }
+ case SPACE_CLIP:
+ {
+ SpaceClip *sc = curarea->spacedata.first;
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+
+ if (clip == NULL) {
+ p->status = GP_STATUS_ERROR;
+ return false;
+ }
+
+ /* set the current area */
+ p->sa = curarea;
+ p->ar = ar;
+ p->v2d = &ar->v2d;
+ p->align_flag = &ts->gpencil_v2d_align;
+
+ invert_m4_m4(p->imat, sc->unistabmat);
+
+ /* custom color for new layer */
+ p->custom_color[0] = 1.0f;
+ p->custom_color[1] = 0.0f;
+ p->custom_color[2] = 0.5f;
+ p->custom_color[3] = 0.9f;
+
+ if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
+ int framenr = ED_space_clip_get_clip_frame_number(sc);
+ MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
+ MovieTrackingMarker *marker = track ? BKE_tracking_marker_get(track, framenr) : NULL;
+
+ if (marker) {
+ p->imat[3][0] -= marker->pos[0];
+ p->imat[3][1] -= marker->pos[1];
+ }
+ else {
+ p->status = GP_STATUS_ERROR;
+ return false;
+ }
+ }
+
+ invert_m4_m4(p->mat, p->imat);
+ copy_m4_m4(p->gsc.mat, p->mat);
+ break;
+ }
+ /* unsupported views */
+ default:
+ {
+ p->status = GP_STATUS_ERROR;
+ if (G.debug & G_DEBUG)
+ printf("Error: Annotations are not supported in this editor\n");
+ return 0;
+ }
+ }
+
+ /* get gp-data */
+ gpd_ptr = ED_gpencil_data_get_pointers(C, &p->ownerPtr);
+ if ((gpd_ptr == NULL) || !ED_gpencil_data_owner_is_annotation(&p->ownerPtr)) {
+ p->status = GP_STATUS_ERROR;
+ if (G.debug & G_DEBUG)
+ printf("Error: Current context doesn't allow for any Annotation data\n");
+ return 0;
+ }
+ else {
+ /* if no existing GPencil block exists, add one */
+ if (*gpd_ptr == NULL) {
+ bGPdata *gpd = BKE_gpencil_data_addnew(bmain, "Annotations");
+ *gpd_ptr = gpd;
+
+ /* mark datablock as being used for annotations */
+ gpd->flag |= GP_DATA_ANNOTATIONS;
+
+ /* annotations always in front of all objects */
+ gpd->xray_mode = GP_XRAY_FRONT;
+ }
+ p->gpd = *gpd_ptr;
+ }
+
+ if (ED_gpencil_session_active() == 0) {
+ /* initialize undo stack,
+ * also, existing undo stack would make buffer drawn
+ */
+ gpencil_undo_init(p->gpd);
+ }
+
+ /* clear out buffer (stored in gp-data), in case something contaminated it */
+ gp_session_validatebuffer(p);
+
+ /* lock axis */
+ p->lock_axis = ts->gp_sculpt.lock_axis;
+
+ return 1;
+}
+
+/* init new painting session */
+static tGPsdata *gp_session_initpaint(bContext *C)
+{
+ tGPsdata *p = NULL;
+
+ /* create new context data */
+ p = MEM_callocN(sizeof(tGPsdata), "Annotation Drawing Data");
+
+ /* Try to initialise context data
+ * WARNING: This may not always succeed (e.g. using GP in an annotation-only context)
+ */
+ if (gp_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.
+ */
+ MEM_freeN(p);
+ return NULL;
+ }
+
+ /* Radius for eraser circle is defined in userprefs */
+ /* NOTE: we do this here, so that if we exit immediately,
+ * erase size won't get lost
+ */
+ p->radius = U.gp_eraser;
+
+ /* return context data for running paint operator */
+ return p;
+}
+
+/* cleanup after a painting session */
+static void gp_session_cleanup(tGPsdata *p)
+{
+ bGPdata *gpd = (p) ? p->gpd : NULL;
+
+ /* error checking */
+ if (gpd == NULL)
+ return;
+
+ /* free stroke buffer */
+ if (gpd->runtime.sbuffer) {
+ /* printf("\t\tGP - free sbuffer\n"); */
+ MEM_freeN(gpd->runtime.sbuffer);
+ gpd->runtime.sbuffer = NULL;
+ }
+
+ /* clear flags */
+ gpd->runtime.sbuffer_size = 0;
+ gpd->runtime.sbuffer_sflag = 0;
+ p->inittime = 0.0;
+}
+
+static void gp_session_free(tGPsdata *p)
+{
+ MEM_freeN(p);
+}
+
+
+/* init new stroke */
+static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Depsgraph *depsgraph)
+{
+ Scene *scene = p->scene;
+ ToolSettings *ts = scene->toolsettings;
+
+ /* get active layer (or add a new one if non-existent) */
+ p->gpl = BKE_gpencil_layer_getactive(p->gpd);
+ if (p->gpl == NULL) {
+ p->gpl = BKE_gpencil_layer_addnew(p->gpd, DATA_("Note"), true);
+
+ if (p->custom_color[3])
+ copy_v3_v3(p->gpl->color, p->custom_color);
+ }
+ if (p->gpl->flag & GP_LAYER_LOCKED) {
+ p->status = GP_STATUS_ERROR;
+ if (G.debug & G_DEBUG)
+ printf("Error: Cannot paint on locked layer\n");
+ return;
+ }
+
+ /* get active frame (add a new one if not matching frame) */
+ if (paintmode == GP_PAINTMODE_ERASER) {
+ /* Eraser mode:
+ * 1) Only allow erasing on the active layer (unlike for 3d-art Grease Pencil),
+ * since we won't be exposing layer locking in the UI
+ * 2) Ensure that p->gpf refers to the frame used for the active layer
+ * (to avoid problems with other tools which expect it to exist)
+ */
+ bool has_layer_to_erase = false;
+
+ if (gpencil_layer_is_editable(p->gpl)) {
+ /* Ensure that there's stuff to erase here (not including selection mask below)... */
+ if (p->gpl->actframe && p->gpl->actframe->strokes.first) {
+ has_layer_to_erase = true;
+ }
+ }
+
+ /* Ensure active frame is set correctly... */
+ p->gpf = p->gpl->actframe;
+
+ /* Restrict eraser to only affecting selected strokes, if the "selection mask" is on
+ * (though this is only available in editmode)
+ */
+ if (p->gpd->flag & GP_DATA_STROKE_EDITMODE) {
+ if (ts->gp_sculpt.flag & GP_BRUSHEDIT_FLAG_SELECT_MASK) {
+ p->flags |= GP_PAINTFLAG_SELECTMASK;
+ }
+ }
+
+ if (has_layer_to_erase == false) {
+ p->status = GP_STATUS_ERROR;
+ //if (G.debug & G_DEBUG)
+ printf("Error: Eraser will not be affecting anything (gpencil_paint_init)\n");
+ return;
+ }
+ }
+ else {
+ /* Drawing Modes - Add a new frame if needed on the active layer */
+ short add_frame_mode = GP_GETFRAME_ADD_NEW;
+
+ if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST)
+ add_frame_mode = GP_GETFRAME_ADD_COPY;
+ else
+ add_frame_mode = GP_GETFRAME_ADD_NEW;
+
+ p->gpf = BKE_gpencil_layer_getframe(p->gpl, CFRA, add_frame_mode);
+
+ if (p->gpf == NULL) {
+ p->status = GP_STATUS_ERROR;
+ if (G.debug & G_DEBUG)
+ printf("Error: No frame created (gpencil_paint_init)\n");
+ return;
+ }
+ else {
+ p->gpf->flag |= GP_FRAME_PAINT;
+ }
+ }
+
+ /* set 'eraser' for this stroke if using eraser */
+ p->paintmode = paintmode;
+ if (p->paintmode == GP_PAINTMODE_ERASER) {
+ p->gpd->runtime.sbuffer_sflag |= GP_STROKE_ERASER;
+
+ /* check if we should respect depth while erasing */
+ if (p->sa->spacetype == SPACE_VIEW3D) {
+ if (p->gpl->flag & GP_LAYER_NO_XRAY) {
+ p->flags |= GP_PAINTFLAG_V3D_ERASER_DEPTH;
+ }
+ }
+ }
+ else {
+ /* disable eraser flags - so that we can switch modes during a session */
+ p->gpd->runtime.sbuffer_sflag &= ~GP_STROKE_ERASER;
+
+ if (p->sa->spacetype == SPACE_VIEW3D) {
+ if (p->gpl->flag & GP_LAYER_NO_XRAY) {
+ p->flags &= ~GP_PAINTFLAG_V3D_ERASER_DEPTH;
+ }
+ }
+ }
+
+ /* set 'initial run' flag, which is only used to denote when a new stroke is starting */
+ p->flags |= GP_PAINTFLAG_FIRSTRUN;
+
+
+ /* when drawing in the camera view, in 2D space, set the subrect */
+ p->subrect = NULL;
+ if ((*p->align_flag & GP_PROJECT_VIEWSPACE) == 0) {
+ if (p->sa->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = p->sa->spacedata.first;
+ RegionView3D *rv3d = p->ar->regiondata;
+
+ /* for camera view set the subrect */
+ if (rv3d->persp == RV3D_CAMOB) {
+ ED_view3d_calc_camera_border(p->scene, depsgraph, p->ar, v3d, rv3d, &p->subrect_data, true); /* no shift */
+ p->subrect = &p->subrect_data;
+ }
+ }
+ }
+
+ /* init stroke point space-conversion settings... */
+ p->gsc.gpd = p->gpd;
+ p->gsc.gpl = p->gpl;
+
+ p->gsc.sa = p->sa;
+ p->gsc.ar = p->ar;
+ p->gsc.v2d = p->v2d;
+
+ p->gsc.subrect_data = p->subrect_data;
+ p->gsc.subrect = p->subrect;
+
+ copy_m4_m4(p->gsc.mat, p->mat);
+
+
+ /* check if points will need to be made in view-aligned space */
+ if (*p->align_flag & GP_PROJECT_VIEWSPACE) {
+ switch (p->sa->spacetype) {
+ case SPACE_VIEW3D:
+ {
+ p->gpd->runtime.sbuffer_sflag |= GP_STROKE_3DSPACE;
+ break;
+ }
+ case SPACE_NODE:
+ {
+ p->gpd->runtime.sbuffer_sflag |= GP_STROKE_2DSPACE;
+ break;
+ }
+ case SPACE_SEQ:
+ {
+ p->gpd->runtime.sbuffer_sflag |= GP_STROKE_2DSPACE;
+ break;
+ }
+ case SPACE_IMAGE:
+ {
+ SpaceImage *sima = (SpaceImage *)p->sa->spacedata.first;
+
+ /* only set these flags if the image editor doesn't have an image active,
+ * otherwise user will be confused by strokes not appearing after they're drawn
+ *
+ * Admittedly, this is a bit hacky, but it works much nicer from an ergonomic standpoint!
+ */
+ if (ELEM(NULL, sima, sima->image)) {
+ /* make strokes be drawn in screen space */
+ p->gpd->runtime.sbuffer_sflag &= ~GP_STROKE_2DSPACE;
+ *(p->align_flag) &= ~GP_PROJECT_VIEWSPACE;
+ }
+ else {
+ p->gpd->runtime.sbuffer_sflag |= GP_STROKE_2DSPACE;
+ }
+ break;
+ }
+ case SPACE_CLIP:
+ {
+ p->gpd->runtime.sbuffer_sflag |= GP_STROKE_2DSPACE;
+ break;
+ }
+ }
+ }
+}
+
+/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */
+static void gp_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)) {
+ View3D *v3d = p->sa->spacedata.first;
+
+ /* need to restore the original projection settings before packing up */
+ view3d_region_operator_needs_opengl(p->win, p->ar);
+ ED_view3d_autodist_init(p->depsgraph, p->ar, v3d, (ts->annotate_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
+ }
+
+ /* check if doing eraser or not */
+ if ((p->gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) {
+ /* simplify stroke before transferring? */
+ gp_stroke_simplify(p);
+
+ /* transfer stroke to frame */
+ gp_stroke_newfrombuffer(p);
+ }
+
+ /* clean up buffer now */
+ gp_session_validatebuffer(p);
+}
+
+/* finish off stroke painting operation */
+static void gp_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);
+ }
+
+ /* "unlock" frame */
+ if (p->gpf)
+ p->gpf->flag &= ~GP_FRAME_PAINT;
+}
+
+/* ------------------------------- */
+
+/* Helper callback for drawing the cursor itself */
+static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr)
+{
+ tGPsdata *p = (tGPsdata *)p_ptr;
+
+ if (p->paintmode == GP_PAINTMODE_ERASER) {
+ GPUVertFormat *format = immVertexFormat();
+ const uint shdr_pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ GPU_line_smooth(true);
+ GPU_blend(true);
+ GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ immUniformColor4ub(255, 100, 100, 20);
+ imm_draw_circle_fill_2d(shdr_pos, x, y, p->radius, 40);
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniformColor4f(1.0f, 0.39f, 0.39f, 0.78f);
+ immUniform1i("colors_len", 0); /* "simple" mode */
+ immUniform1f("dash_width", 12.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ imm_draw_circle_wire_2d(shdr_pos, x, y, p->radius,
+ /* XXX Dashed shader gives bad results with sets of small segments currently,
+ * temp hack around the issue. :( */
+ max_ii(8, p->radius / 2)); /* was fixed 40 */
+
+ immUnbindProgram();
+
+ GPU_blend(false);
+ GPU_line_smooth(false);
+ }
+}
+
+/* Turn brush cursor in 3D view on/off */
+static void gpencil_draw_toggle_eraser_cursor(bContext *C, tGPsdata *p, short enable)
+{
+ if (p->erasercursor && !enable) {
+ /* clear cursor */
+ WM_paint_cursor_end(CTX_wm_manager(C), p->erasercursor);
+ p->erasercursor = NULL;
+ }
+ else if (enable && !p->erasercursor) {
+ /* enable cursor */
+ p->erasercursor = WM_paint_cursor_activate(CTX_wm_manager(C),
+ NULL, /* XXX */
+ gpencil_draw_eraser, p);
+ }
+}
+
+/* Check if tablet eraser is being used (when processing events) */
+static bool gpencil_is_tablet_eraser_active(const wmEvent *event)
+{
+ if (event->tablet_data) {
+ const wmTabletData *wmtab = event->tablet_data;
+ return (wmtab->Active == EVT_TABLET_ERASER);
+ }
+
+ return false;
+}
+
+/* ------------------------------- */
+
+static void gpencil_draw_exit(bContext *C, wmOperator *op)
+{
+ tGPsdata *p = op->customdata;
+
+ /* restore cursor to indicate end of drawing */
+ WM_cursor_modal_restore(CTX_wm_window(C));
+
+ /* don't assume that operator data exists at all */
+ if (p) {
+ /* 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(C, p, false);
+ }
+
+ /* always store the new eraser size to be used again next time
+ * NOTE: Do this even when not in eraser mode, as eraser may
+ * have been toggled at some point.
+ */
+ U.gp_eraser = p->radius;
+
+ /* clear undo stack */
+ gpencil_undo_finish();
+
+ /* cleanup */
+ gp_paint_cleanup(p);
+ gp_session_cleanup(p);
+ gp_session_free(p);
+ p = NULL;
+ }
+
+ op->customdata = NULL;
+}
+
+static void gpencil_draw_cancel(bContext *C, wmOperator *op)
+{
+ /* this is just a wrapper around exit() */
+ gpencil_draw_exit(C, op);
+}
+
+/* ------------------------------- */
+
+
+static int gpencil_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);
+ if ((p == NULL) || (p->status == GP_STATUS_ERROR)) {
+ /* something wasn't set correctly in context */
+ gpencil_draw_exit(C, op);
+ return 0;
+ }
+
+ /* init painting data */
+ gp_paint_initstroke(p, paintmode, CTX_data_depsgraph(C));
+ if (p->status == GP_STATUS_ERROR) {
+ gpencil_draw_exit(C, op);
+ return 0;
+ }
+
+ if (event != NULL) {
+ p->keymodifier = event->keymodifier;
+ }
+ else {
+ p->keymodifier = -1;
+ }
+
+ /* everything is now setup ok */
+ return 1;
+}
+
+
+/* ------------------------------- */
+
+/* ensure that the correct cursor icon is set */
+static void gpencil_draw_cursor_set(tGPsdata *p)
+{
+ if (p->paintmode == GP_PAINTMODE_ERASER)
+ WM_cursor_modal_set(p->win, BC_CROSSCURSOR); /* XXX need a better cursor */
+ else
+ WM_cursor_modal_set(p->win, BC_PAINTBRUSHCURSOR);
+}
+
+/* update UI indicators of status, including cursor and header prints */
+static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p)
+{
+ /* header prints */
+ switch (p->status) {
+ case GP_STATUS_PAINTING:
+ switch (p->paintmode) {
+ case GP_PAINTMODE_DRAW_POLY:
+ /* Provide usage tips, since this is modal, and unintuitive without hints */
+ ED_workspace_status_text(C, IFACE_("Annotation Create Poly: LMB click to place next stroke vertex | "
+ "ESC/Enter to end (or click outside this area)"));
+ break;
+ default:
+ /* Do nothing - the others are self explanatory, exit quickly once the mouse is released
+ * Showing any text would just be annoying as it would flicker.
+ */
+ break;
+ }
+ break;
+
+ case GP_STATUS_IDLING:
+ /* print status info */
+ switch (p->paintmode) {
+ case GP_PAINTMODE_ERASER:
+ ED_workspace_status_text(C, IFACE_("Annotation Eraser: Hold and drag LMB or RMB to erase | "
+ "ESC/Enter to end (or click outside this area)"));
+ break;
+ case GP_PAINTMODE_DRAW_STRAIGHT:
+ ED_workspace_status_text(C, IFACE_("Annotation Line Draw: Hold and drag LMB to draw | "
+ "ESC/Enter to end (or click outside this area)"));
+ break;
+ case GP_PAINTMODE_DRAW:
+ ED_workspace_status_text(C, IFACE_("Annotation Freehand Draw: Hold and drag LMB to draw | "
+ "E/ESC/Enter to end (or click outside this area)"));
+ break;
+ case GP_PAINTMODE_DRAW_POLY:
+ ED_workspace_status_text(C, IFACE_("Annotation Create Poly: LMB click to place next stroke vertex | "
+ "ESC/Enter to end (or click outside this area)"));
+ break;
+
+ default: /* unhandled future cases */
+ ED_workspace_status_text(C, IFACE_("Annotation Session: ESC/Enter to end (or click outside this area)"));
+ break;
+ }
+ break;
+
+ case GP_STATUS_ERROR:
+ case GP_STATUS_DONE:
+ /* clear status string */
+ ED_workspace_status_text(C, NULL);
+ break;
+ }
+}
+
+/* ------------------------------- */
+
+/* create a new stroke point at the point indicated by the painting context */
+static void gpencil_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);
+
+ /* store used values */
+ p->mvalo[0] = p->mval[0];
+ p->mvalo[1] = p->mval[1];
+ p->opressure = p->pressure;
+ }
+ /* 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)) {
+ /* try to add point */
+ short ok = gp_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);
+ /* And start a new one!!! Else, projection errors! */
+ gp_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);
+ }
+ else {
+ p->inittime = p->curtime;
+ }
+ gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
+ }
+ else if (ok == GP_STROKEADD_INVALID) {
+ /* the painting operation cannot continue... */
+ BKE_report(op->reports, RPT_ERROR, "Cannot paint stroke");
+ p->status = GP_STATUS_ERROR;
+
+ if (G.debug & G_DEBUG)
+ printf("Error: Grease-Pencil Paint - Add Point Invalid\n");
+ return;
+ }
+
+ /* store used values */
+ p->mvalo[0] = p->mval[0];
+ p->mvalo[1] = p->mval[1];
+ p->opressure = p->pressure;
+ p->ocurtime = p->curtime;
+ }
+}
+
+/* handle draw event */
+static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsgraph *depsgraph)
+{
+ tGPsdata *p = op->customdata;
+ PointerRNA itemptr;
+ float mousef[2];
+ int tablet = 0;
+
+ /* convert from window-space to area-space mouse coordinates
+ * NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding...
+ */
+ p->mval[0] = event->mval[0] + 1;
+ p->mval[1] = event->mval[1] + 1;
+
+ /* verify key status for straight lines */
+ if ((event->ctrl > 0) || (event->alt > 0)) {
+ if (p->straight[0] == 0) {
+ int dx = abs(p->mval[0] - p->mvalo[0]);
+ int dy = abs(p->mval[1] - p->mvalo[1]);
+ if ((dx > 0) || (dy > 0)) {
+ /* check mouse direction to replace the other coordinate with previous values */
+ if (dx >= dy) {
+ /* horizontal */
+ p->straight[0] = 1;
+ p->straight[1] = p->mval[1]; /* save y */
+ }
+ else {
+ /* vertical */
+ p->straight[0] = 2;
+ p->straight[1] = p->mval[0]; /* save x */
+ }
+ }
+ }
+ }
+ else {
+ p->straight[0] = 0;
+ }
+
+ p->curtime = PIL_check_seconds_timer();
+
+ /* handle pressure sensitivity (which is supplied by tablets) */
+ if (event->tablet_data) {
+ const wmTabletData *wmtab = event->tablet_data;
+
+ tablet = (wmtab->Active != EVT_TABLET_NONE);
+ p->pressure = wmtab->Pressure;
+
+ /* Hack for pressure sensitive eraser on D+RMB when using a tablet:
+ * The pen has to float over the tablet surface, resulting in
+ * zero pressure (T47101). Ignore pressure values if floating
+ * (i.e. "effectively zero" pressure), and only when the "active"
+ * end is the stylus (i.e. the default when not eraser)
+ */
+ if (p->paintmode == GP_PAINTMODE_ERASER) {
+ if ((wmtab->Active != EVT_TABLET_ERASER) && (p->pressure < 0.001f)) {
+ p->pressure = 1.0f;
+ }
+ }
+ }
+ else {
+ /* No tablet data -> No pressure info is available */
+ p->pressure = 1.0f;
+ }
+
+ /* special exception for start of strokes (i.e. maybe for just a dot) */
+ if (p->flags & GP_PAINTFLAG_FIRSTRUN) {
+ p->flags &= ~GP_PAINTFLAG_FIRSTRUN;
+
+ p->mvalo[0] = p->mval[0];
+ p->mvalo[1] = p->mval[1];
+ p->opressure = p->pressure;
+ p->inittime = p->ocurtime = p->curtime;
+ p->straight[0] = 0;
+ p->straight[1] = 0;
+
+ /* special exception here for too high pressure values on first touch in
+ * windows for some tablets, then we just skip first touch...
+ */
+ if (tablet && (p->pressure >= 0.99f))
+ return;
+ }
+
+ /* check if alt key is pressed and limit to straight lines */
+ if (p->straight[0] != 0) {
+ if (p->straight[0] == 1) {
+ /* horizontal */
+ p->mval[1] = p->straight[1]; /* replace y */
+ }
+ else {
+ /* vertical */
+ p->mval[0] = p->straight[1]; /* replace x */
+ }
+ }
+
+ /* fill in stroke data (not actually used directly by gpencil_draw_apply) */
+ RNA_collection_add(op->ptr, "stroke", &itemptr);
+
+ mousef[0] = p->mval[0];
+ mousef[1] = p->mval[1];
+ RNA_float_set_array(&itemptr, "mouse", mousef);
+ RNA_float_set(&itemptr, "pressure", p->pressure);
+ RNA_boolean_set(&itemptr, "is_start", (p->flags & GP_PAINTFLAG_FIRSTRUN) != 0);
+
+ RNA_float_set(&itemptr, "time", p->curtime - p->inittime);
+
+ /* apply the current latest drawing point */
+ gpencil_draw_apply(op, p, depsgraph);
+
+ /* force refresh */
+ ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */
+}
+
+/* ------------------------------- */
+
+/* operator 'redo' (i.e. after changing some properties, but also for repeat last) */
+static int gpencil_draw_exec(bContext *C, wmOperator *op)
+{
+ tGPsdata *p = NULL;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+
+ /* printf("GPencil - Starting Re-Drawing\n"); */
+
+ /* try to initialize context data needed while drawing */
+ if (!gpencil_draw_init(C, op, NULL)) {
+ if (op->customdata) MEM_freeN(op->customdata);
+ /* printf("\tGP - no valid data\n"); */
+ return OPERATOR_CANCELLED;
+ }
+ else
+ p = op->customdata;
+
+ /* printf("\tGP - Start redrawing stroke\n"); */
+
+ /* loop over the stroke RNA elements recorded (i.e. progress of mouse movement),
+ * setting the relevant values in context at each step, then applying
+ */
+ RNA_BEGIN (op->ptr, itemptr, "stroke")
+ {
+ float mousef[2];
+
+ /* printf("\t\tGP - stroke elem\n"); */
+
+ /* get relevant data for this point from stroke */
+ RNA_float_get_array(&itemptr, "mouse", mousef);
+ p->mval[0] = (int)mousef[0];
+ p->mval[1] = (int)mousef[1];
+ p->pressure = RNA_float_get(&itemptr, "pressure");
+ p->curtime = (double)RNA_float_get(&itemptr, "time") + p->inittime;
+
+ if (RNA_boolean_get(&itemptr, "is_start")) {
+ /* if first-run flag isn't set already (i.e. not true first stroke),
+ * then we must terminate the previous one first before continuing
+ */
+ 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);
+ }
+ }
+
+ /* if first run, set previous data too */
+ if (p->flags & GP_PAINTFLAG_FIRSTRUN) {
+ p->flags &= ~GP_PAINTFLAG_FIRSTRUN;
+
+ p->mvalo[0] = p->mval[0];
+ p->mvalo[1] = p->mval[1];
+ p->opressure = p->pressure;
+ p->ocurtime = p->curtime;
+ }
+
+ /* apply this data as necessary now (as per usual) */
+ gpencil_draw_apply(op, p, depsgraph);
+ }
+ RNA_END;
+
+ /* printf("\tGP - done\n"); */
+
+ /* cleanup */
+ gpencil_draw_exit(C, op);
+
+ /* refreshes */
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+/* ------------------------------- */
+
+/* start of interactive drawing part of operator */
+static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Object *ob = CTX_data_active_object(C);
+ tGPsdata *p = NULL;
+
+ /* GPXX Need a better solution */
+ if ((ob != NULL) && (ob->type == OB_GPENCIL)) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot draw annotation with a Grease Pencil object active");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (G.debug & G_DEBUG)
+ printf("GPencil - Starting Drawing\n");
+
+ /* try to initialize context data needed while drawing */
+ if (!gpencil_draw_init(C, op, event)) {
+ if (op->customdata)
+ MEM_freeN(op->customdata);
+ if (G.debug & G_DEBUG)
+ printf("\tGP - no valid data\n");
+ return OPERATOR_CANCELLED;
+ }
+ else
+ p = op->customdata;
+
+ /* 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(C, 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);
+
+ /* only start drawing immediately if we're allowed to do so... */
+ if (RNA_boolean_get(op->ptr, "wait_for_input") == false) {
+ /* hotkey invoked - start drawing */
+ /* printf("\tGP - set first spot\n"); */
+ p->status = GP_STATUS_PAINTING;
+
+ /* handle the initial drawing - i.e. for just doing a simple dot */
+ gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C));
+ op->flag |= OP_IS_MODAL_CURSOR_REGION;
+ }
+ else {
+ /* toolbar invoked - don't start drawing yet... */
+ /* printf("\tGP - hotkey invoked... waiting for click-drag\n"); */
+ op->flag |= OP_IS_MODAL_CURSOR_REGION;
+ }
+
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+ /* add a modal handler for this operator, so that we can then draw continuous strokes */
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */
+static bool gpencil_area_exists(bContext *C, ScrArea *sa_test)
+{
+ bScreen *sc = CTX_wm_screen(C);
+ return (BLI_findindex(&sc->areabase, sa_test) != -1);
+}
+
+static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
+{
+ tGPsdata *p = op->customdata;
+
+ /* we must check that we're still within the area that we're set up to work from
+ * otherwise we could crash (see bug #20586)
+ */
+ if (CTX_wm_area(C) != p->sa) {
+ printf("\t\t\tGP - wrong area execution abort!\n");
+ p->status = GP_STATUS_ERROR;
+ }
+
+ /* printf("\t\tGP - start stroke\n"); */
+
+ /* we may need to set up paint env again if we're resuming */
+ /* 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_depsgraph(C));
+
+ if (p->status != GP_STATUS_ERROR) {
+ p->status = GP_STATUS_PAINTING;
+ op->flag &= ~OP_IS_MODAL_CURSOR_REGION;
+ }
+
+ return op->customdata;
+}
+
+static void gpencil_stroke_end(wmOperator *op)
+{
+ tGPsdata *p = op->customdata;
+
+ gp_paint_cleanup(p);
+
+ gpencil_undo_push(p->gpd);
+
+ gp_session_cleanup(p);
+
+ p->status = GP_STATUS_IDLING;
+ op->flag |= OP_IS_MODAL_CURSOR_REGION;
+
+ p->gpd = NULL;
+ p->gpl = NULL;
+ p->gpf = NULL;
+}
+
+/* events handling during interactive drawing part of operator */
+static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ tGPsdata *p = op->customdata;
+ int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through to support MMB view nav, etc. */
+
+ /* if (event->type == NDOF_MOTION)
+ * return OPERATOR_PASS_THROUGH;
+ * -------------------------------
+ * [mce] Not quite what I was looking
+ * for, but a good start! GP continues to
+ * draw on the screen while the 3D mouse
+ * moves the viewpoint. Problem is that
+ * the stroke is converted to 3D only after
+ * it is finished. This approach should work
+ * better in tools that immediately apply
+ * in 3D space.
+ */
+
+ if (p->status == GP_STATUS_IDLING) {
+ ARegion *ar = CTX_wm_region(C);
+ p->ar = ar;
+ }
+
+ /* we don't pass on key events, GP is used with key-modifiers - prevents Dkey to insert drivers */
+ if (ISKEYBOARD(event->type)) {
+ if (ELEM(event->type, LEFTARROWKEY, DOWNARROWKEY, RIGHTARROWKEY, UPARROWKEY, ZKEY)) {
+ /* allow some keys:
+ * - for frame changing [#33412]
+ * - for undo (during sketching sessions)
+ */
+ }
+ else if (ELEM(event->type, PAD0, PAD1, PAD2, PAD3, PAD4, PAD5, PAD6, PAD7, PAD8, PAD9)) {
+ /* allow numpad keys so that camera/view manipulations can still take place
+ * - PAD0 in particular is really important for Grease Pencil drawing,
+ * as animators may be working "to camera", so having this working
+ * is essential for ensuring that they can quickly return to that view
+ */
+ }
+ else if ((event->type == BKEY) && (event->val == KM_RELEASE)) {
+ /* Add Blank Frame
+ * - Since this operator is non-modal, we can just call it here, and keep going...
+ * - This operator is especially useful when animating
+ */
+ WM_operator_name_call(C, "GPENCIL_OT_blank_frame_add", WM_OP_EXEC_DEFAULT, NULL);
+ estate = OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ estate = OPERATOR_RUNNING_MODAL;
+ }
+ }
+
+ //printf("\tGP - handle modal event...\n");
+
+ /* exit painting mode (and/or end current stroke)
+ * NOTE: cannot do RIGHTMOUSE (as is standard for canceling) as that would break polyline [#32647]
+ */
+ if (ELEM(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY, EKEY)) {
+ /* exit() ends the current stroke before cleaning up */
+ /* printf("\t\tGP - end of paint op + end of stroke\n"); */
+ p->status = GP_STATUS_DONE;
+ estate = OPERATOR_FINISHED;
+ }
+
+ /* toggle painting mode upon mouse-button movement
+ * - LEFTMOUSE = standard drawing (all) / straight line drawing (all) / polyline (toolbox only)
+ * - RIGHTMOUSE = polyline (hotkey) / eraser (all)
+ * (Disabling RIGHTMOUSE case here results in bugs like [#32647])
+ * also making sure we have a valid event value, to not exit too early
+ */
+ if (ELEM(event->type, LEFTMOUSE, RIGHTMOUSE) && (ELEM(event->val, KM_PRESS, KM_RELEASE))) {
+ /* if painting, end stroke */
+ if (p->status == GP_STATUS_PAINTING) {
+ int sketch = 0;
+
+ /* basically, this should be mouse-button up = end stroke
+ * BUT, polyline drawing is an exception -- all knots should be added during one session
+ */
+ sketch |= (p->paintmode == GP_PAINTMODE_DRAW_POLY);
+
+ if (sketch) {
+ /* end stroke only, and then wait to resume painting soon */
+ /* printf("\t\tGP - end stroke only\n"); */
+ gpencil_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
+ */
+ if (p->paintmode == GP_PAINTMODE_ERASER) {
+ p->paintmode = RNA_enum_get(op->ptr, "mode");
+
+ /* if the original mode was *still* eraser,
+ * we'll let it say for now, since this gives
+ * users an opportunity to have visual feedback
+ * when adjusting eraser size
+ */
+ if (p->paintmode != GP_PAINTMODE_ERASER) {
+ /* turn off cursor...
+ * NOTE: this should be enough for now
+ * Just hiding this makes it seem like
+ * you can paint again...
+ */
+ gpencil_draw_toggle_eraser_cursor(C, p, false);
+ }
+ }
+
+ /* we've just entered idling state, so this event was processed (but no others yet) */
+ estate = OPERATOR_RUNNING_MODAL;
+
+ /* stroke could be smoothed, send notifier to refresh screen */
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+ }
+ else {
+ /* printf("\t\tGP - end of stroke + op\n"); */
+ p->status = GP_STATUS_DONE;
+ estate = OPERATOR_FINISHED;
+ }
+ }
+ else if (event->val == KM_PRESS) {
+ bool in_bounds = false;
+
+ /* Check if we're outside the bounds of the active region
+ * NOTE: An exception here is that if launched from the toolbar,
+ * whatever region we're now in should become the new region
+ */
+ if ((p->ar) && (p->ar->regiontype == RGN_TYPE_TOOLS)) {
+ /* Change to whatever region is now under the mouse */
+ ARegion *current_region = BKE_area_find_region_xy(p->sa, RGN_TYPE_ANY, event->x, event->y);
+
+ if (G.debug & G_DEBUG) {
+ printf("found alternative region %p (old was %p) - at %d %d (sa: %d %d -> %d %d)\n",
+ current_region, p->ar, event->x, event->y,
+ p->sa->totrct.xmin, p->sa->totrct.ymin, p->sa->totrct.xmax, p->sa->totrct.ymax);
+ }
+
+ if (current_region) {
+ /* Assume that since we found the cursor in here, it is in bounds
+ * and that this should be the region that we begin drawing in
+ */
+ p->ar = current_region;
+ in_bounds = true;
+ }
+ else {
+ /* Out of bounds, or invalid in some other way */
+ p->status = GP_STATUS_ERROR;
+ estate = OPERATOR_CANCELLED;
+
+ if (G.debug & G_DEBUG)
+ printf("%s: Region under cursor is out of bounds, so cannot be drawn on\n", __func__);
+ }
+ }
+ else if (p->ar) {
+ rcti region_rect;
+
+ /* Perform bounds check using */
+ ED_region_visible_rect(p->ar, &region_rect);
+ in_bounds = BLI_rcti_isect_pt_v(&region_rect, event->mval);
+ }
+ else {
+ /* No region */
+ p->status = GP_STATUS_ERROR;
+ estate = OPERATOR_CANCELLED;
+
+ if (G.debug & G_DEBUG)
+ printf("%s: No active region found in GP Paint session data\n", __func__);
+ }
+
+ if (in_bounds) {
+ /* 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)) {
+ /* turn on eraser */
+ p->paintmode = GP_PAINTMODE_ERASER;
+ }
+ else if (event->type == LEFTMOUSE) {
+ /* restore drawmode to default */
+ p->paintmode = RNA_enum_get(op->ptr, "mode");
+ }
+
+ gpencil_draw_toggle_eraser_cursor(C, p, p->paintmode == GP_PAINTMODE_ERASER);
+
+ /* not painting, so start stroke (this should be mouse-button down) */
+ p = gpencil_stroke_begin(C, op);
+
+ if (p->status == GP_STATUS_ERROR) {
+ estate = OPERATOR_CANCELLED;
+ }
+ }
+ else if (p->status != GP_STATUS_ERROR) {
+ /* User clicked outside bounds of window while idling, so exit paintmode
+ * NOTE: Don't enter this case if an error occurred while finding the
+ * region (as above)
+ */
+ p->status = GP_STATUS_DONE;
+ estate = OPERATOR_FINISHED;
+ }
+ }
+ else if (event->val == KM_RELEASE) {
+ p->status = GP_STATUS_IDLING;
+ op->flag |= OP_IS_MODAL_CURSOR_REGION;
+ }
+ }
+
+ /* handle mode-specific events */
+ if (p->status == GP_STATUS_PAINTING) {
+ /* handle painting mouse-movements? */
+ if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || (p->flags & GP_PAINTFLAG_FIRSTRUN)) {
+ /* handle drawing event */
+ /* printf("\t\tGP - add point\n"); */
+ gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C));
+
+ /* finish painting operation if anything went wrong just now */
+ if (p->status == GP_STATUS_ERROR) {
+ printf("\t\t\t\tGP - add error done!\n");
+ estate = OPERATOR_CANCELLED;
+ }
+ else {
+ /* event handled, so just tag as running modal */
+ /* printf("\t\t\t\tGP - add point handled!\n"); */
+ estate = OPERATOR_RUNNING_MODAL;
+ }
+ }
+ /* eraser size */
+ else if ((p->paintmode == GP_PAINTMODE_ERASER) &&
+ ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE, PADPLUSKEY, PADMINUS))
+ {
+ /* just resize the brush (local version)
+ * TODO: fix the hardcoded size jumps (set to make a visible difference) and hardcoded keys
+ */
+ /* printf("\t\tGP - resize eraser\n"); */
+ switch (event->type) {
+ case WHEELDOWNMOUSE: /* larger */
+ case PADPLUSKEY:
+ p->radius += 5;
+ break;
+
+ case WHEELUPMOUSE: /* smaller */
+ case PADMINUS:
+ p->radius -= 5;
+
+ if (p->radius <= 0)
+ p->radius = 1;
+ break;
+ }
+
+ /* force refresh */
+ ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */
+
+ /* event handled, so just tag as running modal */
+ estate = OPERATOR_RUNNING_MODAL;
+ }
+ /* there shouldn't be any other events, but just in case there are, let's swallow them
+ * (i.e. to prevent problems with undo)
+ */
+ else {
+ /* swallow event to save ourselves trouble */
+ estate = OPERATOR_RUNNING_MODAL;
+ }
+ }
+
+ /* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */
+ if (0 == gpencil_area_exists(C, p->sa))
+ estate = OPERATOR_CANCELLED;
+ else {
+ /* update status indicators - cursor, header, etc. */
+ gpencil_draw_status_indicators(C, p);
+ gpencil_draw_cursor_set(p); /* cursor may have changed outside our control - T44084 */
+ }
+
+ /* process last operations before exiting */
+ switch (estate) {
+ case OPERATOR_FINISHED:
+ /* one last flush before we're done */
+ gpencil_draw_exit(C, op);
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+ break;
+
+ case OPERATOR_CANCELLED:
+ gpencil_draw_exit(C, op);
+ break;
+
+ case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH:
+ /* event doesn't need to be handled */
+#if 0
+ printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n",
+ event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE);
+#endif
+ break;
+ }
+
+ /* return status code */
+ return estate;
+}
+
+/* ------------------------------- */
+
+static const EnumPropertyItem prop_gpencil_drawmodes[] = {
+ {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", "Draw freehand stroke(s)"},
+ {GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", "Draw straight line segment(s)"},
+ {GP_PAINTMODE_DRAW_POLY, "DRAW_POLY", 0, "Draw Poly Line", "Click to place endpoints of straight line segments (connected)"},
+ {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", "Erase Annotation strokes"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+void GPENCIL_OT_annotate(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Annotation Draw";
+ ot->idname = "GPENCIL_OT_annotate";
+ 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;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
+
+ /* settings for drawing */
+ ot->prop = RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements");
+
+ prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+
+ /* NOTE: wait for input is enabled by default, so that all UI code can work properly without needing users to know about this */
+ prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "Wait for first click instead of painting immediately");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+}
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index ec4310213ef..180fb65e743 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -46,6 +46,7 @@
#include "BLF_api.h"
#include "BLT_translation.h"
+#include "DNA_brush_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -55,8 +56,13 @@
#include "DNA_object_types.h"
#include "BKE_context.h"
+#include "BKE_brush.h"
#include "BKE_global.h"
+#include "BKE_paint.h"
#include "BKE_gpencil.h"
+#include "BKE_image.h"
+
+#include "DEG_depsgraph.h"
#include "WM_api.h"
@@ -74,6 +80,10 @@
#include "UI_interface_icons.h"
#include "UI_resources.h"
+#include "IMB_imbuf_types.h"
+
+#include "gpencil_intern.h"
+
/* ************************************************** */
/* GREASE PENCIL DRAWING */
@@ -88,8 +98,7 @@ typedef enum eDrawStrokeFlags {
GP_DRAWDATA_NO_XRAY = (1 << 5), /* don't draw xray in 3D view (which is default) */
GP_DRAWDATA_NO_ONIONS = (1 << 6), /* no onionskins should be drawn (for animation playback) */
GP_DRAWDATA_VOLUMETRIC = (1 << 7), /* draw strokes as "volumetric" circular billboards */
- GP_DRAWDATA_FILL = (1 << 8), /* fill insides/bounded-regions of strokes */
- GP_DRAWDATA_HQ_FILL = (1 << 9) /* Use high quality fill */
+ GP_DRAWDATA_FILL = (1 << 8) /* fill insides/bounded-regions of strokes */
} eDrawStrokeFlags;
@@ -100,12 +109,12 @@ typedef enum eDrawStrokeFlags {
#endif
/* conversion utility (float --> normalized unsigned byte) */
-#define F2UB(x) (unsigned char)(255.0f * x)
+#define F2UB(x) (uchar)(255.0f * x)
/* ----- Tool Buffer Drawing ------ */
/* helper functions to set color of buffer point */
-static void gp_set_tpoint_varying_color(const tGPspoint *pt, const float ink[4], unsigned attrib_id)
+static void gp_set_tpoint_varying_color(const tGPspoint *pt, const float ink[4], uint attrib_id)
{
float alpha = ink[3] * pt->strength;
CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
@@ -119,7 +128,7 @@ static void gp_set_point_uniform_color(const bGPDspoint *pt, const float ink[4])
immUniformColor3fvAlpha(ink, alpha);
}
-static void gp_set_point_varying_color(const bGPDspoint *pt, const float ink[4], unsigned attrib_id)
+static void gp_set_point_varying_color(const bGPDspoint *pt, const float ink[4], uint attrib_id)
{
float alpha = ink[3] * pt->strength;
CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
@@ -134,7 +143,7 @@ static void gp_draw_stroke_buffer_fill(const tGPspoint *points, int totpoints, f
}
int tot_triangles = totpoints - 2;
/* allocate memory for temporary areas */
- unsigned int(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, "GP Stroke buffer temp triangulation");
+ uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, "GP Stroke buffer temp triangulation");
float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, "GP Stroke buffer temp 2d points");
/* Convert points to array and triangulate
@@ -146,18 +155,18 @@ static void gp_draw_stroke_buffer_fill(const tGPspoint *points, int totpoints, f
points2d[i][0] = pt->x;
points2d[i][1] = pt->y;
}
- BLI_polyfill_calc((const float(*)[2])points2d, (unsigned int)totpoints, 0, (unsigned int(*)[3])tmp_triangles);
+ BLI_polyfill_calc((const float(*)[2])points2d, (uint)totpoints, 0, (uint(*)[3])tmp_triangles);
/* draw triangulation data */
if (tot_triangles > 0) {
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
/* Draw all triangles for filling the polygon */
- immBegin(GWN_PRIM_TRIS, tot_triangles * 3);
+ immBegin(GPU_PRIM_TRIS, tot_triangles * 3);
/* TODO: use batch instead of immediate mode, to share vertices */
const tGPspoint *pt;
@@ -208,9 +217,9 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short
return;
}
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
const tGPspoint *pt = points;
@@ -218,7 +227,7 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short
/* if drawing a single point, draw it larger */
GPU_point_size((float)(thickness + 2) * points->pressure);
immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
gp_set_tpoint_varying_color(pt, ink, color);
immVertex2iv(pos, &pt->x);
}
@@ -228,7 +237,7 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short
/* draw stroke curve */
GPU_line_width(max_ff(oldpressure * thickness, 1.0));
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints);
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints);
/* TODO: implement this with a geometry shader to draw one continuous tapered stroke */
@@ -247,13 +256,13 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short
draw_points = 0;
GPU_line_width(max_ff(pt->pressure * thickness, 1.0f));
- immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints - i + 1);
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1);
/* need to roll-back one point to ensure that there are no gaps in the stroke */
if (i != 0) {
gp_set_tpoint_varying_color(pt - 1, ink, color);
immVertex2iv(pos, &(pt - 1)->x);
- ++draw_points;
+ draw_points++;
}
oldpressure = pt->pressure; /* reset our threshold */
@@ -262,7 +271,7 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short
/* now the point we want */
gp_set_tpoint_varying_color(pt, ink, color);
immVertex2iv(pos, &pt->x);
- ++draw_points;
+ draw_points++;
}
/* need to have 2 points to avoid immEnd assert error */
if (draw_points < 2) {
@@ -319,14 +328,14 @@ static void gp_draw_stroke_volumetric_buffer(const tGPspoint *points, int totpoi
if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D))
return;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
GPU_enable_program_point_size();
- immBegin(GWN_PRIM_POINTS, totpoints);
+ immBegin(GPU_PRIM_POINTS, totpoints);
const tGPspoint *pt = points;
for (int i = 0; i < totpoints; i++, pt++) {
@@ -346,14 +355,14 @@ static void gp_draw_stroke_volumetric_2d(const bGPDspoint *points, int totpoints
int offsx, int offsy, int winx, int winy,
const float diff_mat[4][4], const float ink[4])
{
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
GPU_enable_program_point_size();
- immBegin(GWN_PRIM_POINTS, totpoints);
+ immBegin(GPU_PRIM_POINTS, totpoints);
const bGPDspoint *pt = points;
for (int i = 0; i < totpoints; i++, pt++) {
@@ -379,14 +388,14 @@ static void gp_draw_stroke_volumetric_3d(
const bGPDspoint *points, int totpoints, short thickness,
const float ink[4])
{
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- uint size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
GPU_enable_program_point_size();
- immBegin(GWN_PRIM_POINTS, totpoints);
+ immBegin(GPU_PRIM_POINTS, totpoints);
const bGPDspoint *pt = points;
for (int i = 0; i < totpoints && pt; i++, pt++) {
@@ -402,6 +411,50 @@ static void gp_draw_stroke_volumetric_3d(
/* --------------- Stroke Fills ----------------- */
+/* calc bounding box in 2d using flat projection data */
+static void gp_calc_2d_bounding_box(const float(*points2d)[2], int totpoints, float minv[2], float maxv[2], bool expand)
+{
+ copy_v2_v2(minv, points2d[0]);
+ copy_v2_v2(maxv, points2d[0]);
+
+ for (int i = 1; i < totpoints; i++) {
+ /* min */
+ if (points2d[i][0] < minv[0]) {
+ minv[0] = points2d[i][0];
+ }
+ if (points2d[i][1] < minv[1]) {
+ minv[1] = points2d[i][1];
+ }
+ /* max */
+ if (points2d[i][0] > maxv[0]) {
+ maxv[0] = points2d[i][0];
+ }
+ if (points2d[i][1] > maxv[1]) {
+ maxv[1] = points2d[i][1];
+ }
+ }
+ /* If not expanded, use a perfect square */
+ if (expand == false) {
+ if (maxv[0] > maxv[1]) {
+ maxv[1] = maxv[0];
+ }
+ else {
+ maxv[0] = maxv[1];
+ }
+ }
+}
+
+/* calc texture coordinates using flat projected points */
+static void gp_calc_stroke_text_coordinates(const float(*points2d)[2], int totpoints, float minv[2], float maxv[2], float(*r_uv)[2])
+{
+ float d[2];
+ d[0] = maxv[0] - minv[0];
+ d[1] = maxv[1] - minv[1];
+ for (int i = 0; i < totpoints; i++) {
+ r_uv[i][0] = (points2d[i][0] - minv[0]) / d[0];
+ r_uv[i][1] = (points2d[i][1] - minv[1]) / d[1];
+ }
+}
/* Get points of stroke always flat to view not affected by camera view or view position */
static void gp_stroke_2d_flat(const bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction)
@@ -447,7 +500,6 @@ static void gp_stroke_2d_flat(const bGPDspoint *points, int totpoints, float(*po
*r_direction = (int)locy[2];
}
-
/* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was modified) */
static void gp_triangulate_stroke_fill(bGPDstroke *gps)
{
@@ -455,14 +507,23 @@ static void gp_triangulate_stroke_fill(bGPDstroke *gps)
/* allocate memory for temporary areas */
gps->tot_triangles = gps->totpoints - 2;
- unsigned int (*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles, "GP Stroke temp triangulation");
+ uint (*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles, "GP Stroke temp triangulation");
float (*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints, "GP Stroke temp 2d points");
+ float(*uv)[2] = MEM_mallocN(sizeof(*uv) * gps->totpoints, "GP Stroke temp 2d uv data");
int direction = 0;
/* convert to 2d and triangulate */
gp_stroke_2d_flat(gps->points, gps->totpoints, points2d, &direction);
- BLI_polyfill_calc(points2d, (unsigned int)gps->totpoints, direction, tmp_triangles);
+ BLI_polyfill_calc(points2d, (uint)gps->totpoints, direction, tmp_triangles);
+
+ /* calc texture coordinates automatically */
+ float minv[2];
+ float maxv[2];
+ /* first needs bounding box data */
+ gp_calc_2d_bounding_box((const float(*)[2])points2d, gps->totpoints, minv, maxv, false);
+ /* calc uv data */
+ gp_calc_stroke_text_coordinates((const float(*)[2])points2d, gps->totpoints, minv, maxv, uv);
/* Number of triangles */
gps->tot_triangles = gps->totpoints - 2;
@@ -476,7 +537,12 @@ static void gp_triangulate_stroke_fill(bGPDstroke *gps)
}
for (int i = 0; i < gps->tot_triangles; i++) {
- memcpy(gps->triangles[i].verts, tmp_triangles[i], sizeof(uint[3]));
+ bGPDtriangle *stroke_triangle = &gps->triangles[i];
+ memcpy(stroke_triangle->verts, tmp_triangles[i], sizeof(uint[3]));
+ /* copy texture coordinates */
+ copy_v2_v2(stroke_triangle->uv[0], uv[tmp_triangles[i][0]]);
+ copy_v2_v2(stroke_triangle->uv[1], uv[tmp_triangles[i][1]]);
+ copy_v2_v2(stroke_triangle->uv[2], uv[tmp_triangles[i][2]]);
}
}
else {
@@ -493,73 +559,128 @@ static void gp_triangulate_stroke_fill(bGPDstroke *gps)
}
/* clear memory */
- if (tmp_triangles) MEM_freeN(tmp_triangles);
- if (points2d) MEM_freeN(points2d);
+ MEM_SAFE_FREE(tmp_triangles);
+ MEM_SAFE_FREE(points2d);
+ MEM_SAFE_FREE(uv);
}
-
-/* draw fills for shapes */
-static void gp_draw_stroke_fill(
- bGPdata *gpd, bGPDstroke *gps,
- int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float color[4])
+/* add a new fill point and texture coordinates to vertex buffer */
+static void gp_add_filldata_tobuffer(
+ const bGPDspoint *pt, const float uv[2], uint pos, uint texcoord, short flag,
+ int offsx, int offsy, int winx, int winy, const float diff_mat[4][4])
{
float fpt[3];
+ float co[2];
- BLI_assert(gps->totpoints >= 3);
+ mul_v3_m4v3(fpt, diff_mat, &pt->x);
+ /* if 2d, need conversion */
+ if (!(flag & GP_STROKE_3DSPACE)) {
+ gp_calc_2d_stroke_fxy(fpt, flag, offsx, offsy, winx, winy, co);
+ copy_v2_v2(fpt, co);
+ fpt[2] = 0.0f; /* 2d always is z=0.0f */
+ }
- bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps);
+ immAttrib2f(texcoord, uv[0], uv[1]); /* texture coordinates */
+ immVertex3fv(pos, fpt); /* position */
+}
- /* Triangulation fill if high quality flag is enabled */
- if (palcolor->flag & PC_COLOR_HQ_FILL) {
- /* Calculate triangles cache for filling area (must be done only after changes) */
- if ((gps->flag & GP_STROKE_RECALC_CACHES) || (gps->tot_triangles == 0) || (gps->triangles == NULL)) {
- gp_triangulate_stroke_fill(gps);
- }
- BLI_assert(gps->tot_triangles >= 1);
+#if 0 /* GPXX disabled, not used in annotations */
+/* assign image texture for filling stroke */
+static int gp_set_filling_texture(Image *image, short flag)
+{
+ ImBuf *ibuf;
+ uint *bind = &image->bindcode[TEXTARGET_TEXTURE_2D];
+ int error = GL_NO_ERROR;
+ ImageUser iuser = { NULL };
+ void *lock;
- uint pos;
- if (gps->flag & GP_STROKE_3DSPACE) {
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- }
- else {
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- }
+ iuser.ok = true;
- immUniformColor4fv(color);
+ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
- /* Draw all triangles for filling the polygon (cache must be calculated before) */
- immBegin(GWN_PRIM_TRIS, gps->tot_triangles * 3);
- /* TODO: use batch instead of immediate mode, to share vertices */
+ if (ibuf == NULL || ibuf->rect == NULL) {
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ return (int)GL_INVALID_OPERATION;
+ }
- bGPDtriangle *stroke_triangle = gps->triangles;
- bGPDspoint *pt;
+ GPU_create_gl_tex(bind, ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y, GL_TEXTURE_2D,
+ false, false, image);
- if (gps->flag & GP_STROKE_3DSPACE) {
- for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) {
- for (int j = 0; j < 3; j++) {
- pt = &gps->points[stroke_triangle->verts[j]];
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- immVertex3fv(pos, fpt);
- }
- }
- }
- else {
- for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) {
- for (int j = 0; j < 3; j++) {
- float co[2];
- pt = &gps->points[stroke_triangle->verts[j]];
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co);
- immVertex3fv(pos, fpt);
- }
- }
- }
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ if (flag & GP_STYLE_COLOR_TEX_CLAMP) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ }
+ else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ }
+ BKE_image_release_ibuf(image, ibuf, NULL);
- immEnd();
- immUnbindProgram();
+ return error;
+}
+#endif
+
+/* draw fills for shapes */
+static void gp_draw_stroke_fill(
+ bGPdata *gpd, bGPDstroke *gps,
+ int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float color[4])
+{
+ BLI_assert(gps->totpoints >= 3);
+ Material *ma = gpd->mat[gps->mat_nr];
+ MaterialGPencilStyle *gp_style = ma->gp_style;
+
+ /* Calculate triangles cache for filling area (must be done only after changes) */
+ if ((gps->flag & GP_STROKE_RECALC_CACHES) || (gps->tot_triangles == 0) || (gps->triangles == NULL)) {
+ gp_triangulate_stroke_fill(gps);
+ }
+ BLI_assert(gps->tot_triangles >= 1);
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_GPENCIL_FILL);
+
+ immUniformColor4fv(color);
+ immUniform4fv("color2", gp_style->mix_rgba);
+ immUniform1i("fill_type", gp_style->fill_style);
+ immUniform1f("mix_factor", gp_style->mix_factor);
+
+ immUniform1f("gradient_angle", gp_style->gradient_angle);
+ immUniform1f("gradient_radius", gp_style->gradient_radius);
+ immUniform1f("pattern_gridsize", gp_style->pattern_gridsize);
+ immUniform2fv("gradient_scale", gp_style->gradient_scale);
+ immUniform2fv("gradient_shift", gp_style->gradient_shift);
+
+ immUniform1f("texture_angle", gp_style->texture_angle);
+ immUniform2fv("texture_scale", gp_style->texture_scale);
+ immUniform2fv("texture_offset", gp_style->texture_offset);
+ immUniform1f("texture_opacity", gp_style->texture_opacity);
+ immUniform1i("t_mix", gp_style->flag & GP_STYLE_COLOR_TEX_MIX ? 1 : 0);
+ immUniform1i("t_flip", gp_style->flag & GP_STYLE_COLOR_FLIP_FILL ? 1 : 0);
+#if 0 /* GPXX disabled, not used in annotations */
+ /* image texture */
+ if ((gp_style->fill_style == GP_STYLE_FILL_STYLE_TEXTURE) || (gp_style->flag & GP_STYLE_COLOR_TEX_MIX)) {
+ gp_set_filling_texture(gp_style->ima, gp_style->flag);
}
+#endif
+ /* Draw all triangles for filling the polygon (cache must be calculated before) */
+ immBegin(GPU_PRIM_TRIS, gps->tot_triangles * 3);
+ /* TODO: use batch instead of immediate mode, to share vertices */
+
+ const bGPDtriangle *stroke_triangle = gps->triangles;
+ for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) {
+ for (int j = 0; j < 3; j++) {
+ gp_add_filldata_tobuffer(
+ &gps->points[stroke_triangle->verts[j]], stroke_triangle->uv[j],
+ pos, texcoord, gps->flag,
+ offsx, offsy, winx, winy, diff_mat);
+ }
+ }
+
+ immEnd();
+ immUnbindProgram();
}
/* ----- Existing Strokes Drawing (3D and Point) ------ */
@@ -575,8 +696,8 @@ static void gp_draw_stroke_point(
float fpt[3];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
if (sflag & GP_STROKE_3DSPACE) {
immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
@@ -594,94 +715,88 @@ static void gp_draw_stroke_point(
/* set point thickness (since there's only one of these) */
immUniform1f("size", (float)(thickness + 2) * pt->pressure);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex3fv(pos, fpt);
immEnd();
immUnbindProgram();
}
-/* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */
-static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thickness, bool UNUSED(debug),
- short UNUSED(sflag), const float diff_mat[4][4], const float ink[4], bool cyclic)
+/* 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)
{
+ bGPDspoint *points = tgpw->gps->points;
+ int totpoints = tgpw->gps->totpoints;
+
+ const float viewport[2] = { (float)tgpw->winx, (float)tgpw->winy };
float curpressure = points[0].pressure;
float fpt[3];
- float cyclic_fpt[3];
- int draw_points = 0;
-
- /* if cyclic needs one vertex more */
- int cyclic_add = 0;
- if (cyclic) {
- ++cyclic_add;
- }
+ /* if cyclic needs more vertex */
+ int cyclic_add = (cyclic) ? 1 : 0;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ uint thickattrib = GPU_vertformat_attr_add(format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_GPENCIL_STROKE);
+ immUniform2fv("Viewport", viewport);
+ immUniform1f("pixsize", tgpw->rv3d->pixsize);
+ immUniform1f("pixelsize", U.pixelsize);
+ float obj_scale = (tgpw->ob->size[0] + tgpw->ob->size[1] + tgpw->ob->size[2]) / 3.0f;
- /* TODO: implement this with a geometry shader to draw one continuous tapered stroke */
+ immUniform1f("objscale", obj_scale);
+ int keep_size = (int)((tgpw->gpd) && (tgpw->gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS));
+ immUniform1i("keep_size", keep_size);
+ immUniform1i("pixfactor", tgpw->gpd->pixfactor);
+ immUniform1i("xraymode", tgpw->gpd->xray_mode);
/* draw stroke curve */
GPU_line_width(max_ff(curpressure * thickness, 1.0f));
- immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints + cyclic_add);
+ immBeginAtMost(GPU_PRIM_LINE_STRIP_ADJ, totpoints + cyclic_add + 2);
const bGPDspoint *pt = points;
- for (int i = 0; i < totpoints; i++, pt++) {
- gp_set_point_varying_color(pt, ink, color);
- /* if there was a significant pressure change, stop the curve, change the thickness of the stroke,
- * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP)
- * Note: we want more visible levels of pressures when thickness is bigger.
- */
- if (fabsf(pt->pressure - curpressure) > 0.2f / (float)thickness) {
- /* if the pressure changes before get at least 2 vertices, need to repeat last point to avoid assert in immEnd() */
- if (draw_points < 2) {
- const bGPDspoint *pt2 = pt - 1;
- mul_v3_m4v3(fpt, diff_mat, &pt2->x);
- immVertex3fv(pos, fpt);
+ for (int i = 0; i < totpoints; i++, pt++) {
+ /* first point for adjacency (not drawn) */
+ if (i == 0) {
+ gp_set_point_varying_color(points, ink, color);
+ immAttrib1f(thickattrib, max_ff(curpressure * thickness, 1.0f));
+ if ((cyclic) && (totpoints > 2)) {
+ mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + totpoints - 1)->x);
}
- immEnd();
- draw_points = 0;
-
- curpressure = pt->pressure;
- GPU_line_width(max_ff(curpressure * thickness, 1.0f));
- immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints - i + 1 + cyclic_add);
-
- /* need to roll-back one point to ensure that there are no gaps in the stroke */
- if (i != 0) {
- const bGPDspoint *pt2 = pt - 1;
- mul_v3_m4v3(fpt, diff_mat, &pt2->x);
- gp_set_point_varying_color(pt2, ink, color);
- immVertex3fv(pos, fpt);
- ++draw_points;
+ else {
+ mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + 1)->x);
}
+ mul_v3_fl(fpt, -1.0f);
+ immVertex3fv(pos, fpt);
}
-
- /* now the point we want */
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
+ /* set point */
+ gp_set_point_varying_color(pt, ink, color);
+ immAttrib1f(thickattrib, max_ff(curpressure * thickness, 1.0f));
+ mul_v3_m4v3(fpt, tgpw->diff_mat, &pt->x);
immVertex3fv(pos, fpt);
- ++draw_points;
- if (cyclic && i == 0) {
- /* save first point to use in cyclic */
- copy_v3_v3(cyclic_fpt, fpt);
- }
+ curpressure = pt->pressure;
}
- if (cyclic) {
+ if (cyclic && totpoints > 2) {
/* draw line to first point to complete the cycle */
- immVertex3fv(pos, cyclic_fpt);
- ++draw_points;
- }
+ immAttrib1f(thickattrib, max_ff(points->pressure * thickness, 1.0f));
+ mul_v3_m4v3(fpt, tgpw->diff_mat, &points->x);
+ immVertex3fv(pos, fpt);
- /* if less of two points, need to repeat last point to avoid assert in immEnd() */
- if (draw_points < 2) {
- const bGPDspoint *pt2 = pt - 1;
- mul_v3_m4v3(fpt, diff_mat, &pt2->x);
- gp_set_point_varying_color(pt2, ink, color);
+ /* now add adjacency point (not drawn) */
+ immAttrib1f(thickattrib, max_ff((points + 1)->pressure * thickness, 1.0f));
+ mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + 1)->x);
+ immVertex3fv(pos, fpt);
+ }
+ /* last adjacency point (not drawn) */
+ else {
+ gp_set_point_varying_color(points + totpoints - 1, ink, color);
+ immAttrib1f(thickattrib, max_ff(curpressure * thickness, 1.0f));
+ mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + totpoints - 2)->x);
+ mul_v3_fl(fpt, -1.0f);
immVertex3fv(pos, fpt);
}
@@ -692,8 +807,9 @@ static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thi
/* ----- Fancy 2D-Stroke Drawing ------ */
/* draw a given stroke in 2d */
-static void gp_draw_stroke_2d(const bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag,
- bool UNUSED(debug), int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float ink[4])
+static void gp_draw_stroke_2d(
+ const bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag,
+ bool UNUSED(debug), int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float ink[4])
{
/* otherwise thickness is twice that of the 3D view */
float thickness = (float)thickness_s * 0.5f;
@@ -716,12 +832,12 @@ static void gp_draw_stroke_2d(const bGPDspoint *points, int totpoints, short thi
int i;
float fpt[3];
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GWN_PRIM_TRI_STRIP, totpoints * 2 + 4);
+ immBegin(GPU_PRIM_TRI_STRIP, totpoints * 2 + 4);
/* get x and y coordinates from first point */
mul_v3_m4v3(fpt, diff_mat, &points->x);
@@ -900,10 +1016,7 @@ static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag)
}
/* draw a set of strokes */
-static void gp_draw_strokes(
- bGPdata *gpd, const bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag,
- bool debug, short lthick, const float opacity, const float tintcolor[4],
- const bool onion, const bool custonion, const float diff_mat[4][4])
+static void gp_draw_strokes(tGPDdraw *tgpw)
{
float tcolor[4];
float tfill[4];
@@ -912,31 +1025,41 @@ static void gp_draw_strokes(
GPU_enable_program_point_size();
- for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ for (bGPDstroke *gps = tgpw->t_gpf->strokes.first; gps; gps = gps->next) {
/* check if stroke can be drawn */
- if (gp_can_draw_stroke(gps, dflag) == false) {
+ if (gp_can_draw_stroke(gps, tgpw->dflag) == false) {
continue;
}
/* check if the color is visible */
- bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps);
- if ((palcolor == NULL) ||
- (palcolor->flag & PC_COLOR_HIDE) ||
+ Material *ma = tgpw->gpd->mat[gps->mat_nr];
+ MaterialGPencilStyle *gp_style = ma->gp_style;
+
+ if ((gp_style == NULL) ||
+ (gp_style->flag & GP_STYLE_COLOR_HIDE) ||
/* if onion and ghost flag do not draw*/
- (onion && (palcolor->flag & PC_COLOR_ONIONSKIN)))
+ (tgpw->onion && (gp_style->flag & GP_STYLE_COLOR_ONIONSKIN)))
+ {
+ continue;
+ }
+
+ /* if disable fill, the colors with fill must be omitted too except fill boundary strokes */
+ if ((tgpw->disable_fill == 1) &&
+ (gp_style->fill_rgba[3] > 0.0f) &&
+ ((gps->flag & GP_STROKE_NOFILL) == 0))
{
continue;
}
/* calculate thickness */
- sthickness = gps->thickness + lthick;
+ sthickness = gps->thickness + tgpw->lthick;
if (sthickness <= 0) {
continue;
}
/* check which stroke-drawer to use */
- if (dflag & GP_DRAWDATA_ONLY3D) {
- const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY);
+ if (tgpw->dflag & GP_DRAWDATA_ONLY3D) {
+ const int no_xray = (tgpw->dflag & GP_DRAWDATA_NO_XRAY);
int mask_orig = 0;
if (no_xray) {
@@ -951,57 +1074,64 @@ static void gp_draw_strokes(
/* 3D Fill */
//if ((dflag & GP_DRAWDATA_FILL) && (gps->totpoints >= 3)) {
- if (gps->totpoints >= 3) {
- /* set color using palette, tint color and opacity */
- interp_v3_v3v3(tfill, palcolor->fill, tintcolor, tintcolor[3]);
- tfill[3] = palcolor->fill[3] * opacity;
- if (tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) {
+ if ((gps->totpoints >= 3) && (tgpw->disable_fill != 1)) {
+ /* set color using material, tint color and opacity */
+ interp_v3_v3v3(tfill, gp_style->fill_rgba, tgpw->tintcolor, tgpw->tintcolor[3]);
+ tfill[3] = gp_style->fill_rgba[3] * tgpw->opacity;
+ if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0)) {
const float *color;
- if (!onion) {
+ if (!tgpw->onion) {
color = tfill;
}
else {
- if (custonion) {
- color = tintcolor;
+ if (tgpw->custonion) {
+ color = tgpw->tintcolor;
}
else {
- ARRAY_SET_ITEMS(tfill, UNPACK3(palcolor->fill), tintcolor[3]);
+ ARRAY_SET_ITEMS(tfill, UNPACK3(gp_style->fill_rgba), tgpw->tintcolor[3]);
color = tfill;
}
}
- gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat, color);
+ gp_draw_stroke_fill(
+ tgpw->gpd, gps,
+ tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy, tgpw->diff_mat, color);
}
}
/* 3D Stroke */
- /* set color using palette, tint color and opacity */
- if (!onion) {
- interp_v3_v3v3(tcolor, palcolor->color, tintcolor, tintcolor[3]);
- tcolor[3] = palcolor->color[3] * opacity;
+ /* set color using material tint color and opacity */
+ if (!tgpw->onion) {
+ interp_v3_v3v3(tcolor, gp_style->stroke_rgba, tgpw->tintcolor, tgpw->tintcolor[3]);
+ tcolor[3] = gp_style->stroke_rgba[3] * tgpw->opacity;
copy_v4_v4(ink, tcolor);
}
else {
- if (custonion) {
- copy_v4_v4(ink, tintcolor);
+ if (tgpw->custonion) {
+ copy_v4_v4(ink, tgpw->tintcolor);
}
else {
- ARRAY_SET_ITEMS(tcolor, palcolor->color[0], palcolor->color[1], palcolor->color[2], opacity);
+ ARRAY_SET_ITEMS(tcolor, UNPACK3(gp_style->stroke_rgba), tgpw->opacity);
copy_v4_v4(ink, tcolor);
}
}
- if (palcolor->flag & PC_COLOR_VOLUMETRIC) {
+ if (gp_style->mode == GP_STYLE_MODE_DOTS) {
/* volumetric stroke drawing */
- gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, sthickness, ink);
+ if (tgpw->disable_fill != 1) {
+ gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, sthickness, ink);
+ }
}
else {
/* 3D Lines - OpenGL primitives-based */
if (gps->totpoints == 1) {
- gp_draw_stroke_point(gps->points, sthickness, dflag, gps->flag, offsx, offsy, winx, winy,
- diff_mat, ink);
+ if (tgpw->disable_fill != 1) {
+ gp_draw_stroke_point(gps->points, sthickness, tgpw->dflag, gps->flag,
+ tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy,
+ tgpw->diff_mat, ink);
+ }
}
else {
- gp_draw_stroke_3d(gps->points, gps->totpoints, sthickness, debug, gps->flag,
- diff_mat, ink, gps->flag & GP_STROKE_CYCLIC);
+ tgpw->gps = gps;
+ gp_draw_stroke_3d(tgpw, sthickness, ink, gps->flag & GP_STROKE_CYCLIC);
}
}
if (no_xray) {
@@ -1014,58 +1144,63 @@ static void gp_draw_strokes(
else {
/* 2D - Fill */
if (gps->totpoints >= 3) {
- /* set color using palette, tint color and opacity */
- interp_v3_v3v3(tfill, palcolor->fill, tintcolor, tintcolor[3]);
- tfill[3] = palcolor->fill[3] * opacity;
- if (tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) {
+ /* set color using material, tint color and opacity */
+ interp_v3_v3v3(tfill, gp_style->fill_rgba, tgpw->tintcolor, tgpw->tintcolor[3]);
+ tfill[3] = gp_style->fill_rgba[3] * tgpw->opacity;
+ if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0)) {
const float *color;
- if (!onion) {
+ if (!tgpw->onion) {
color = tfill;
}
else {
- if (custonion) {
- color = tintcolor;
+ if (tgpw->custonion) {
+ color = tgpw->tintcolor;
}
else {
- ARRAY_SET_ITEMS(tfill, palcolor->fill[0], palcolor->fill[1], palcolor->fill[2],
- tintcolor[3]);
+ ARRAY_SET_ITEMS(tfill, UNPACK3(gp_style->fill_rgba), tgpw->tintcolor[3]);
color = tfill;
}
}
- gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat, color);
+ gp_draw_stroke_fill(
+ tgpw->gpd, gps,
+ tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy, tgpw->diff_mat, color);
}
}
/* 2D Strokes... */
- /* set color using palette, tint color and opacity */
- if (!onion) {
- interp_v3_v3v3(tcolor, palcolor->color, tintcolor, tintcolor[3]);
- tcolor[3] = palcolor->color[3] * opacity;
+ /* set color using material, tint color and opacity */
+ if (!tgpw->onion) {
+ interp_v3_v3v3(tcolor, gp_style->stroke_rgba, tgpw->tintcolor, tgpw->tintcolor[3]);
+ tcolor[3] = gp_style->stroke_rgba[3] * tgpw->opacity;
copy_v4_v4(ink, tcolor);
}
else {
- if (custonion) {
- copy_v4_v4(ink, tintcolor);
+ if (tgpw->custonion) {
+ copy_v4_v4(ink, tgpw->tintcolor);
}
else {
- ARRAY_SET_ITEMS(tcolor, palcolor->color[0], palcolor->color[1], palcolor->color[2], opacity);
+ ARRAY_SET_ITEMS(tcolor, UNPACK3(gp_style->stroke_rgba), tgpw->opacity);
copy_v4_v4(ink, tcolor);
}
}
- if (palcolor->flag & PC_COLOR_VOLUMETRIC) {
+ if (gp_style->mode == GP_STYLE_MODE_DOTS) {
/* blob/disk-based "volumetric" drawing */
- gp_draw_stroke_volumetric_2d(gps->points, gps->totpoints, sthickness, dflag, gps->flag,
- offsx, offsy, winx, winy, diff_mat, ink);
+ gp_draw_stroke_volumetric_2d(
+ gps->points, gps->totpoints, sthickness, tgpw->dflag, gps->flag,
+ tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy, tgpw->diff_mat, ink);
}
else {
/* normal 2D strokes */
if (gps->totpoints == 1) {
- gp_draw_stroke_point(gps->points, sthickness, dflag, gps->flag, offsx, offsy, winx, winy,
- diff_mat, ink);
+ gp_draw_stroke_point(
+ gps->points, sthickness, tgpw->dflag, gps->flag,
+ tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy,
+ tgpw->diff_mat, ink);
}
else {
- gp_draw_stroke_2d(gps->points, gps->totpoints, sthickness, dflag, gps->flag, debug,
- offsx, offsy, winx, winy, diff_mat, ink);
+ gp_draw_stroke_2d(
+ gps->points, gps->totpoints, sthickness, tgpw->dflag, gps->flag, false,
+ tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy, tgpw->diff_mat, ink);
}
}
}
@@ -1114,14 +1249,16 @@ static void gp_draw_strokes_edit(
if ((gps->flag & GP_STROKE_SELECT) == 0)
continue;
- /* verify palette color lock */
+ /* verify color lock */
{
- bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps);
- if (palcolor != NULL) {
- if (palcolor->flag & PC_COLOR_HIDE) {
+ Material *ma = gpd->mat[gps->mat_nr];
+ MaterialGPencilStyle *gp_style = ma->gp_style;
+
+ if (gp_style != NULL) {
+ if (gp_style->flag & GP_STYLE_COLOR_HIDE) {
continue;
}
- if (((lflag & GP_LAYER_UNLOCK_COLOR) == 0) && (palcolor->flag & PC_COLOR_LOCKED)) {
+ if (((lflag & GP_LAYER_UNLOCK_COLOR) == 0) && (gp_style->flag & GP_STYLE_COLOR_LOCKED)) {
continue;
}
}
@@ -1143,28 +1280,29 @@ static void gp_draw_strokes_edit(
}
/* for now, we assume that the base color of the points is not too close to the real color */
- /* set color using palette */
- bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps);
+ /* set color using material */
+ Material *ma = gpd->mat[gps->mat_nr];
+ MaterialGPencilStyle *gp_style = ma->gp_style;
float selectColor[4];
UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor);
selectColor[3] = alpha;
- Gwn_VertFormat *format = immVertexFormat();
+ GPUVertFormat *format = immVertexFormat();
uint pos; /* specified later */
- uint size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
if (gps->flag & GP_STROKE_3DSPACE) {
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
}
else {
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR);
}
- immBegin(GWN_PRIM_POINTS, gps->totpoints);
+ immBegin(GPU_PRIM_POINTS, gps->totpoints);
/* Draw start and end point differently if enabled stroke direction hint */
bool show_direction_hint = (gpd->flag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1);
@@ -1189,7 +1327,7 @@ static void gp_draw_strokes_edit(
immAttrib1f(size, vsize);
}
else {
- immAttrib3fv(color, palcolor->color);
+ immAttrib3fv(color, gp_style->stroke_rgba);
immAttrib1f(size, bsize);
}
@@ -1229,98 +1367,75 @@ static void gp_draw_strokes_edit(
/* ----- General Drawing ------ */
-/* draw onion-skinning for a layer */
-static void gp_draw_onionskins(
- bGPdata *gpd, const bGPDlayer *gpl, const bGPDframe *gpf, int offsx, int offsy, int winx, int winy,
- int UNUSED(cfra), int dflag, bool debug, const float diff_mat[4][4])
+
+/* draw interpolate strokes (used only while operator is running) */
+void ED_gp_draw_interpolation(const bContext *C, tGPDinterpolate *tgpi, const int type)
{
- const float default_color[3] = {UNPACK3(U.gpencil_new_layer_col)};
- const float alpha = 1.0f;
+ tGPDdraw tgpw;
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+ tGPDinterpolate_layer *tgpil;
+ Object *obact = CTX_data_active_object(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+
float color[4];
- /* 1) Draw Previous Frames First */
- if (gpl->flag & GP_LAYER_GHOST_PREVCOL) {
- copy_v3_v3(color, gpl->gcolor_prev);
- }
- else {
- copy_v3_v3(color, default_color);
+ UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, color);
+ color[3] = 0.6f;
+ int dflag = 0;
+ /* if 3d stuff, enable flags */
+ if (type == REGION_DRAW_POST_VIEW) {
+ dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS);
}
- if (gpl->gstep > 0) {
- /* draw previous frames first */
- for (bGPDframe *gf = gpf->prev; gf; gf = gf->prev) {
- /* check if frame is drawable */
- if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
- /* alpha decreases with distance from curframe index */
- float fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1));
- color[3] = alpha * fac * 0.66f;
- gp_draw_strokes(gpd, gf, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color,
- true, gpl->flag & GP_LAYER_GHOST_PREVCOL, diff_mat);
- }
- else
- break;
- }
- }
- else if (gpl->gstep == 0) {
- /* draw the strokes for the ghost frames (at half of the alpha set by user) */
- if (gpf->prev) {
- color[3] = (alpha / 7);
- gp_draw_strokes(gpd, gpf->prev, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color,
- true, gpl->flag & GP_LAYER_GHOST_PREVCOL, diff_mat);
- }
- }
- else {
- /* don't draw - disabled */
- }
+ tgpw.rv3d = rv3d;
+ tgpw.depsgraph = depsgraph;
+ tgpw.ob = obact;
+ tgpw.gpd = tgpi->gpd;
+ tgpw.offsx = 0;
+ tgpw.offsy = 0;
+ tgpw.winx = tgpi->ar->winx;
+ tgpw.winy = tgpi->ar->winy;
+ tgpw.dflag = dflag;
- /* 2) Now draw next frames */
- if (gpl->flag & GP_LAYER_GHOST_NEXTCOL) {
- copy_v3_v3(color, gpl->gcolor_next);
- }
- else {
- copy_v3_v3(color, default_color);
- }
+ /* turn on alpha-blending */
+ glEnable(GL_BLEND);
+ for (tgpil = tgpi->ilayers.first; tgpil; tgpil = tgpil->next) {
+ /* calculate parent position */
+ ED_gpencil_parent_location(depsgraph, obact, tgpi->gpd, tgpil->gpl, tgpw.diff_mat);
+ if (tgpil->interFrame) {
+ tgpw.gpl = tgpil->gpl;
+ tgpw.gpf = tgpil->interFrame;
+ tgpw.t_gpf = tgpil->interFrame;
- if (gpl->gstep_next > 0) {
- /* now draw next frames */
- for (bGPDframe *gf = gpf->next; gf; gf = gf->next) {
- /* check if frame is drawable */
- if ((gf->framenum - gpf->framenum) <= gpl->gstep_next) {
- /* alpha decreases with distance from curframe index */
- float fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep_next + 1));
- color[3] = alpha * fac * 0.66f;
- gp_draw_strokes(gpd, gf, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color,
- true, gpl->flag & GP_LAYER_GHOST_NEXTCOL, diff_mat);
- }
- else
- break;
- }
- }
- else if (gpl->gstep_next == 0) {
- /* draw the strokes for the ghost frames (at half of the alpha set by user) */
- if (gpf->next) {
- color[3] = (alpha / 4);
- gp_draw_strokes(gpd, gpf->next, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color,
- true, gpl->flag & GP_LAYER_GHOST_NEXTCOL, diff_mat);
+ tgpw.lthick = tgpil->gpl->line_change;
+ tgpw.opacity = 1.0;
+ copy_v4_v4(tgpw.tintcolor, color);
+ tgpw.onion = true;
+ tgpw.custonion = true;
+
+ gp_draw_strokes(&tgpw);
}
}
- else {
- /* don't draw - disabled */
- }
+ glDisable(GL_BLEND);
}
/* draw interpolate strokes (used only while operator is running) */
-void ED_gp_draw_interpolation(tGPDinterpolate *tgpi, const int type)
+void ED_gp_draw_primitives(const bContext *C, tGPDprimitive *tgpi, const int type)
{
- tGPDinterpolate_layer *tgpil;
- float diff_mat[4][4];
- float color[4];
+ tGPDdraw tgpw;
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
- int offsx = 0;
- int offsy = 0;
- int winx = tgpi->ar->winx;
- int winy = tgpi->ar->winy;
+ /* if idle, do not draw */
+ if (tgpi->flag == 0) {
+ return;
+ }
+ Object *obact = CTX_data_active_object(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C); \
+
+ float color[4];
UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, color);
color[3] = 0.6f;
int dflag = 0;
@@ -1329,32 +1444,71 @@ void ED_gp_draw_interpolation(tGPDinterpolate *tgpi, const int type)
dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS);
}
+ tgpw.rv3d = rv3d;
+ tgpw.depsgraph = depsgraph;
+ tgpw.ob = obact;
+ tgpw.gpd = tgpi->gpd;
+ tgpw.offsx = 0;
+ tgpw.offsy = 0;
+ tgpw.winx = tgpi->ar->winx;
+ tgpw.winy = tgpi->ar->winy;
+ tgpw.dflag = dflag;
+
/* turn on alpha-blending */
GPU_blend(true);
- for (tgpil = tgpi->ilayers.first; tgpil; tgpil = tgpil->next) {
- /* calculate parent position */
- ED_gpencil_parent_location(tgpil->gpl, diff_mat);
- if (tgpil->interFrame) {
- gp_draw_strokes(tgpi->gpd, tgpil->interFrame, offsx, offsy, winx, winy, dflag, false,
- tgpil->gpl->thickness, 1.0f, color, true, true, diff_mat);
+ /* calculate parent position */
+ ED_gpencil_parent_location(depsgraph, obact, tgpi->gpd, tgpi->gpl, tgpw.diff_mat);
+ if (tgpi->gpf) {
+ tgpw.gps = tgpi->gpf->strokes.first;
+ if (tgpw.gps->totpoints > 0) {
+ tgpw.gpl = tgpi->gpl;
+ tgpw.gpf = tgpi->gpf;
+ tgpw.t_gpf = tgpi->gpf;
+
+ tgpw.lthick = tgpi->gpl->line_change;
+ tgpw.opacity = 1.0;
+ copy_v4_v4(tgpw.tintcolor, color);
+ tgpw.onion = true;
+ tgpw.custonion = true;
+
+ gp_draw_strokes(&tgpw);
}
}
GPU_blend(false);
}
+/* wrapper to draw strokes for filling operator */
+void ED_gp_draw_fill(tGPDdraw *tgpw)
+{
+ gp_draw_strokes(tgpw);
+}
+
/* loop over gpencil data layers, drawing them */
-static void gp_draw_data_layers(
- const bGPDbrush *brush, float alpha, bGPdata *gpd,
+static void gp_draw_data_layers(RegionView3D *rv3d,
+ const Brush *brush, float alpha, Object *ob, bGPdata *gpd,
int offsx, int offsy, int winx, int winy, int cfra, int dflag)
{
float diff_mat[4][4];
+ tGPDdraw tgpw;
+
+ tgpw.rv3d = rv3d;
+ tgpw.depsgraph = NULL; /* XXX: This is not used here */
+ tgpw.ob = ob;
+ tgpw.gpd = gpd;
+ tgpw.gpl = NULL;
+ tgpw.gpf = NULL;
+ tgpw.t_gpf = NULL;
+ tgpw.offsx = offsx;
+ tgpw.offsy = offsy;
+ tgpw.winx = winx;
+ tgpw.winy = winy;
+ tgpw.dflag = dflag;
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* calculate parent position */
- ED_gpencil_parent_location(gpl, diff_mat);
+ ED_gpencil_parent_location(tgpw.depsgraph, ob, gpd, gpl, diff_mat);
- bool debug = (gpl->flag & GP_LAYER_DRAWDEBUG);
- short lthick = brush->thickness + gpl->thickness;
+ short lthick = brush->size + gpl->line_change;
/* don't draw layer if hidden */
if (gpl->flag & GP_LAYER_HIDE)
@@ -1383,30 +1537,20 @@ static void gp_draw_data_layers(
/* volumetric strokes... */
GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_VOLUMETRIC), GP_DRAWDATA_VOLUMETRIC);
- /* HQ fills... */
- GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_HQ_FILL), GP_DRAWDATA_HQ_FILL);
-
#undef GP_DRAWFLAG_APPLY
- /* Draw 'onionskins' (frame left + right)
- * - It is only possible to show these if the option is enabled
- * - The "no onions" flag prevents ghosts from appearing during animation playback/scrubbing
- * and in renders
- * - The per-layer "always show" flag however overrides the playback/render restriction,
- * allowing artists to selectively turn onionskins on/off during playback
- */
- if ((gpl->flag & GP_LAYER_ONIONSKIN) &&
- ((dflag & GP_DRAWDATA_NO_ONIONS) == 0 || (gpl->flag & GP_LAYER_GHOST_ALWAYS)))
- {
- /* Drawing method - only immediately surrounding (gstep = 0),
- * or within a frame range on either side (gstep > 0)
- */
- gp_draw_onionskins(gpd, gpl, gpf, offsx, offsy, winx, winy, cfra, dflag, debug, diff_mat);
- }
+ tgpw.gpl = gpl;
+ tgpw.gpf = gpf;
+ tgpw.t_gpf = gpf; // XXX?
+ tgpw.lthick = gpl->line_change;
+ tgpw.opacity = gpl->opacity;
+ copy_v4_v4(tgpw.tintcolor, gpl->tintcolor);
+ tgpw.onion = false;
+ tgpw.custonion = false;
+ copy_m4_m4(tgpw.diff_mat, diff_mat);
/* draw the strokes already in active frame */
- gp_draw_strokes(gpd, gpf, offsx, offsy, winx, winy, dflag, debug, gpl->thickness,
- gpl->opacity, gpl->tintcolor, false, false, diff_mat);
+ gp_draw_strokes(&tgpw);
/* Draw verts of selected strokes
* - when doing OpenGL renders, we don't want to be showing these, as that ends up flickering
@@ -1435,19 +1579,25 @@ static void gp_draw_data_layers(
* It should also be noted that sbuffer contains temporary point types
* i.e. tGPspoints NOT bGPDspoints
*/
- if (gpd->sflag & PC_COLOR_VOLUMETRIC) {
- gp_draw_stroke_volumetric_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick,
- dflag, gpd->scolor);
+ if (gpd->runtime.mode == GP_STYLE_MODE_DOTS) {
+ gp_draw_stroke_volumetric_buffer(
+ gpd->runtime.sbuffer,
+ gpd->runtime.sbuffer_size, lthick,
+ dflag, gpd->runtime.scolor);
}
else {
- gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, gpd->scolor, gpd->sfill);
+ gp_draw_stroke_buffer(
+ gpd->runtime.sbuffer,
+ gpd->runtime.sbuffer_size, lthick,
+ dflag, gpd->runtime.sbuffer_sflag,
+ gpd->runtime.scolor, gpd->runtime.sfill);
}
}
}
}
/* draw a short status message in the top-right corner */
-static void gp_draw_status_text(const bGPdata *gpd, ARegion *ar)
+static void UNUSED_FUNCTION(gp_draw_status_text)(const bGPdata *gpd, ARegion *ar)
{
rcti rect;
@@ -1493,8 +1643,8 @@ static void gp_draw_status_text(const bGPdata *gpd, ARegion *ar)
}
/* draw grease-pencil datablock */
-static void gp_draw_data(
- const bGPDbrush *brush, float alpha, bGPdata *gpd,
+static void gp_draw_data(RegionView3D *rv3d,
+ const Brush *brush, float alpha, Object *ob, bGPdata *gpd,
int offsx, int offsy, int winx, int winy, int cfra, int dflag)
{
/* turn on smooth lines (i.e. anti-aliasing) */
@@ -1510,7 +1660,7 @@ static void gp_draw_data(
GPU_blend(true);
/* draw! */
- gp_draw_data_layers(brush, alpha, gpd, offsx, offsy, winx, winy, cfra, dflag);
+ gp_draw_data_layers(rv3d, brush, alpha, ob, gpd, offsx, offsy, winx, winy, cfra, dflag);
/* turn off alpha blending, then smooth lines */
GPU_blend(false); // alpha blending
@@ -1519,33 +1669,22 @@ static void gp_draw_data(
/* if we have strokes for scenes (3d view)/clips (movie clip editor)
* and objects/tracks, multiple data blocks have to be drawn */
-static void gp_draw_data_all(Scene *scene, bGPdata *gpd, int offsx, int offsy, int winx, int winy,
- int cfra, int dflag, const char spacetype)
+static void gp_draw_data_all(
+ RegionView3D *rv3d, Scene *scene, bGPdata *gpd, int offsx, int offsy, int winx, int winy,
+ int cfra, int dflag, const char UNUSED(spacetype))
{
bGPdata *gpd_source = NULL;
- ToolSettings *ts;
- bGPDbrush *brush = NULL;
+ ToolSettings *ts = NULL;
+ Brush *brush = NULL;
if (scene) {
ts = scene->toolsettings;
- brush = BKE_gpencil_brush_getactive(ts);
- /* if no brushes, create default set */
- if (brush == NULL) {
- BKE_gpencil_brush_init_presets(ts);
- brush = BKE_gpencil_brush_getactive(ts);
- }
-
- if (spacetype == SPACE_VIEW3D) {
- gpd_source = (scene->gpd ? scene->gpd : NULL);
- }
- else if (spacetype == SPACE_CLIP && scene->clip) {
- /* currently drawing only gpencil data from either clip or track, but not both - XXX fix logic behind */
- gpd_source = (scene->clip->gpd ? scene->clip->gpd : NULL);
- }
+ brush = BKE_brush_getactive_gpencil(ts);
if (gpd_source) {
if (brush != NULL) {
- gp_draw_data(brush, ts->gp_sculpt.alpha, gpd_source,
- offsx, offsy, winx, winy, cfra, dflag);
+ gp_draw_data(
+ rv3d, brush, 1.0f, NULL, gpd_source,
+ offsx, offsy, winx, winy, cfra, dflag);
}
}
}
@@ -1554,76 +1693,70 @@ static void gp_draw_data_all(Scene *scene, bGPdata *gpd, int offsx, int offsy, i
* if gpd_source == gpd, we don't have any object/track data and we can skip */
if (gpd_source == NULL || (gpd_source && gpd_source != gpd)) {
if (brush != NULL) {
- gp_draw_data(brush, ts->gp_sculpt.alpha, gpd,
- offsx, offsy, winx, winy, cfra, dflag);
+ gp_draw_data(
+ rv3d, brush, 1.0f, NULL, gpd,
+ offsx, offsy, winx, winy, cfra, dflag);
}
}
}
/* ----- 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...
- * ............................ */
-/* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */
-void ED_gpencil_draw_2dimage(const bContext *C)
+/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly
+ * Note: this gets called twice - first time with only3d=true to draw 3d-strokes,
+ * second time with only3d=false for screen-aligned strokes */
+void ED_gpencil_draw_view3d(
+ wmWindowManager *wm,
+ Scene *scene,
+ ViewLayer *view_layer,
+ struct Depsgraph *depsgraph,
+ View3D *v3d,
+ ARegion *ar,
+ bool only3d)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- Scene *scene = CTX_data_scene(C);
-
- int offsx, offsy, sizex, sizey;
- int dflag = GP_DRAWDATA_NOSTATUS;
+ int dflag = 0;
+ RegionView3D *rv3d = ar->regiondata;
+ int offsx, offsy, winx, winy;
- bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX
+ /* check that we have grease-pencil stuff to draw */
+ // XXX: This is the only place that still uses this function
+ bGPdata *gpd = ED_gpencil_data_get_active_v3d(view_layer);
if (gpd == NULL) return;
- /* calculate rect */
- switch (sa->spacetype) {
- case SPACE_IMAGE: /* image */
- case SPACE_CLIP: /* clip */
- {
- /* just draw using standard scaling (settings here are currently ignored anyways) */
- /* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */
- offsx = 0;
- offsy = 0;
- sizex = ar->winx;
- sizey = ar->winy;
+ /* when rendering to the offscreen buffer we don't want to
+ * deal with the camera border, otherwise map the coords to the camera border. */
+ if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) {
+ rctf rectf;
+ ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &rectf, true); /* no shift */
+
+ offsx = round_fl_to_int(rectf.xmin);
+ offsy = round_fl_to_int(rectf.ymin);
+ winx = round_fl_to_int(rectf.xmax - rectf.xmin);
+ winy = round_fl_to_int(rectf.ymax - rectf.ymin);
+ }
+ else {
+ offsx = 0;
+ offsy = 0;
+ winx = ar->winx;
+ winy = ar->winy;
+ }
- wmOrtho2(ar->v2d.cur.xmin, ar->v2d.cur.xmax, ar->v2d.cur.ymin, ar->v2d.cur.ymax);
+ /* set flags */
+ if (only3d) {
+ /* 3D strokes/3D space:
+ * - only 3D space points
+ * - don't status text either (as it's the wrong space)
+ */
+ dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS);
+ }
- dflag |= GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_IEDITHACK;
- break;
- }
- case SPACE_SEQ: /* sequence */
- {
- /* just draw using standard scaling (settings here are currently ignored anyways) */
- offsx = 0;
- offsy = 0;
- sizex = ar->winx;
- sizey = ar->winy;
-
- /* NOTE: I2D was used in 2.4x, but the old settings for that have been deprecated
- * and everything moved to standard View2d
- */
- dflag |= GP_DRAWDATA_ONLYV2D;
- break;
- }
- default: /* for spacetype not yet handled */
- offsx = 0;
- offsy = 0;
- sizex = ar->winx;
- sizey = ar->winy;
-
- dflag |= GP_DRAWDATA_ONLYI2D;
- break;
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
+ /* don't draw status text when "only render" flag is set */
+ dflag |= GP_DRAWDATA_NOSTATUS;
}
- if (ED_screen_animation_playing(wm)) {
+ if ((wm == NULL) || ED_screen_animation_playing(wm)) {
/* don't show onionskins during animation playback/scrub (i.e. it obscures the poses)
* OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes)
*/
@@ -1631,85 +1764,46 @@ void ED_gpencil_draw_2dimage(const bContext *C)
}
/* draw it! */
- gp_draw_data_all(scene, gpd, offsx, offsy, sizex, sizey, CFRA, dflag, sa->spacetype);
+ gp_draw_data_all(rv3d, scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype);
}
-/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly
- * Note: this gets called twice - first time with onlyv2d=true to draw 'canvas' strokes,
- * second time with onlyv2d=false for screen-aligned strokes */
-void ED_gpencil_draw_view2d(const bContext *C, bool onlyv2d)
-{
- wmWindowManager *wm = CTX_wm_manager(C);
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- Scene *scene = CTX_data_scene(C);
- int dflag = 0;
-
- /* check that we have grease-pencil stuff to draw */
- if (sa == NULL) return;
- bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX
- if (gpd == NULL) return;
-
- /* special hack for Image Editor */
- /* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */
- if (ELEM(sa->spacetype, SPACE_IMAGE, SPACE_CLIP))
- dflag |= GP_DRAWDATA_IEDITHACK;
-
- /* draw it! */
- if (onlyv2d) dflag |= (GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_NOSTATUS);
- if (ED_screen_animation_playing(wm)) dflag |= GP_DRAWDATA_NO_ONIONS;
-
- gp_draw_data_all(scene, gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag, sa->spacetype);
-
- /* draw status text (if in screen/pixel-space) */
- if (!onlyv2d) {
- gp_draw_status_text(gpd, ar);
- }
-}
-
-/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly
- * Note: this gets called twice - first time with only3d=true to draw 3d-strokes,
- * second time with only3d=false for screen-aligned strokes */
-void ED_gpencil_draw_view3d(wmWindowManager *wm,
- Scene *scene,
- ViewLayer *view_layer,
- struct Depsgraph *depsgraph,
- View3D *v3d,
- ARegion *ar,
- bool only3d)
+/* draw grease-pencil sketches to specified 3d-view for gp object
+ * assuming that matrices are already set correctly
+ */
+void ED_gpencil_draw_view3d_object(wmWindowManager *wm, Scene *scene, Depsgraph *depsgraph, Object *ob, View3D *v3d, ARegion *ar, bool only3d)
{
int dflag = 0;
RegionView3D *rv3d = ar->regiondata;
- int offsx, offsy, winx, winy;
+ int offsx, offsy, winx, winy;
/* check that we have grease-pencil stuff to draw */
- bGPdata *gpd = ED_gpencil_data_get_active_v3d(scene, view_layer);
+ bGPdata *gpd = ob->data;
if (gpd == NULL) return;
/* when rendering to the offscreen buffer we don't want to
- * deal with the camera border, otherwise map the coords to the camera border. */
+ * deal with the camera border, otherwise map the coords to the camera border. */
if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) {
rctf rectf;
ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &rectf, true); /* no shift */
offsx = round_fl_to_int(rectf.xmin);
offsy = round_fl_to_int(rectf.ymin);
- winx = round_fl_to_int(rectf.xmax - rectf.xmin);
- winy = round_fl_to_int(rectf.ymax - rectf.ymin);
+ winx = round_fl_to_int(rectf.xmax - rectf.xmin);
+ winy = round_fl_to_int(rectf.ymax - rectf.ymin);
}
else {
offsx = 0;
offsy = 0;
- winx = ar->winx;
- winy = ar->winy;
+ winx = ar->winx;
+ winy = ar->winy;
}
/* set flags */
if (only3d) {
/* 3D strokes/3D space:
- * - only 3D space points
- * - don't status text either (as it's the wrong space)
- */
+ * - only 3D space points
+ * - don't status text either (as it's the wrong space)
+ */
dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS);
}
@@ -1720,20 +1814,23 @@ void ED_gpencil_draw_view3d(wmWindowManager *wm,
if ((wm == NULL) || ED_screen_animation_playing(wm)) {
/* don't show onionskins during animation playback/scrub (i.e. it obscures the poses)
- * OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes)
- */
+ * OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes)
+ */
dflag |= GP_DRAWDATA_NO_ONIONS;
}
/* draw it! */
- gp_draw_data_all(scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype);
+ ToolSettings *ts = scene->toolsettings;
+ Brush *brush = BKE_brush_getactive_gpencil(ts);
+ if (brush != NULL) {
+ gp_draw_data(rv3d, brush, 1.0f, ob, gpd,
+ offsx, offsy, winx, winy, CFRA, dflag);
+ }
}
-void ED_gpencil_draw_ex(Scene *scene, bGPdata *gpd, int winx, int winy, const int cfra, const char spacetype)
+void ED_gpencil_draw_ex(RegionView3D *rv3d, Scene *scene, bGPdata *gpd, int winx, int winy, const int cfra, const char spacetype)
{
int dflag = GP_DRAWDATA_NOSTATUS | GP_DRAWDATA_ONLYV2D;
- gp_draw_data_all(scene, gpd, 0, 0, winx, winy, cfra, dflag, spacetype);
+ gp_draw_data_all(rv3d, scene, gpd, 0, 0, winx, winy, cfra, dflag, spacetype);
}
-
-/* ************************************************** */
diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c
index 5e62a87caf3..88f935eb8bf 100644
--- a/source/blender/editors/gpencil/editaction_gpencil.c
+++ b/source/blender/editors/gpencil/editaction_gpencil.c
@@ -492,6 +492,8 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
/* make a copy of stroke, then of its points array */
gpsn = MEM_dupallocN(gps);
gpsn->points = MEM_dupallocN(gps->points);
+ gpsn->dvert = MEM_dupallocN(gps->dvert);
+ BKE_gpencil_stroke_weights_duplicate(gps, gpsn);
/* duplicate triangle information */
gpsn->triangles = MEM_dupallocN(gps->triangles);
/* append stroke to frame */
diff --git a/source/blender/editors/gpencil/gpencil_add_monkey.c b/source/blender/editors/gpencil/gpencil_add_monkey.c
new file mode 100644
index 00000000000..78286e3f672
--- /dev/null
+++ b/source/blender/editors/gpencil/gpencil_add_monkey.c
@@ -0,0 +1,1566 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2017 Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Antonio Vazquez, Matias Mendiola
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/gpencil/gpencil_add_monkey.c
+ * \ingroup edgpencil
+ */
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_context.h"
+#include "BKE_gpencil.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "ED_gpencil.h"
+
+/* Definition of the most important info from a color */
+typedef struct ColorTemplate {
+ const char *name;
+ float line[4];
+ float fill[4];
+} ColorTemplate;
+
+/* Add color an ensure duplications (matched by name) */
+static int gpencil_monkey_color(Main *bmain, Object *ob, const ColorTemplate *pct)
+{
+ short *totcol = give_totcolp(ob);
+ Material *ma = NULL;
+ for (short i = 0; i < *totcol; i++) {
+ ma = give_current_material(ob, i + 1);
+ if (STREQ(ma->id.name, pct->name)) {
+ return i;
+ }
+ }
+
+ /* create a new one */
+ BKE_object_material_slot_add(bmain, ob);
+ ma = BKE_material_add_gpencil(bmain, pct->name);
+ assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
+
+ copy_v4_v4(ma->gp_style->stroke_rgba, pct->line);
+ copy_v4_v4(ma->gp_style->fill_rgba, pct->fill);
+
+ return BKE_gpencil_get_material_index(ob, ma) - 1;
+}
+
+/* ***************************************************************** */
+/* Monkey Geometry */
+
+static const float data0[538 * GP_PRIM_DATABUF_SIZE] = {
+ -0.509f, 0.0f, -0.156f, 0.267f, 0.362f, -0.522f, 0.0f, -0.159f, 0.31f, 0.407f, -0.531f, 0.0f, -0.16f, 0.347f, 0.426f, -0.543f, -0.0f, -0.162f, 0.38f, 0.439f,
+ -0.554f, -0.0f, -0.163f, 0.409f, 0.448f, -0.566f, -0.0f, -0.165f, 0.433f, 0.458f, -0.578f, -0.0f, -0.167f, 0.454f, 0.478f, -0.591f, -0.0f, -0.168f, 0.471f, 0.5f,
+ -0.604f, -0.0f, -0.169f, 0.485f, 0.51f, -0.619f, -0.0f, -0.171f, 0.496f, 0.516f, -0.634f, -0.0f, -0.171f, 0.504f, 0.519f, -0.649f, -0.0f, -0.171f, 0.511f, 0.519f,
+ -0.665f, -0.0f, -0.17f, 0.516f, 0.521f, -0.681f, -0.0f, -0.17f, 0.521f, 0.53f, -0.697f, -0.0f, -0.169f, 0.524f, 0.533f, -0.713f, -0.0f, -0.167f, 0.527f, 0.533f,
+ -0.729f, 0.0f, -0.165f, 0.53f, 0.534f, -0.745f, 0.0f, -0.161f, 0.531f, 0.534f, -0.761f, 0.0f, -0.157f, 0.533f, 0.535f, -0.777f, 0.0f, -0.153f, 0.534f, 0.535f,
+ -0.792f, 0.0f, -0.148f, 0.535f, 0.536f, -0.808f, 0.0f, -0.144f, 0.535f, 0.535f, -0.822f, 0.0f, -0.139f, 0.536f, 0.537f, -0.837f, 0.0f, -0.133f, 0.536f, 0.537f,
+ -0.852f, 0.0f, -0.128f, 0.536f, 0.537f, -0.866f, 0.0f, -0.122f, 0.536f, 0.537f, -0.88f, 0.0f, -0.115f, 0.536f, 0.537f, -0.894f, 0.0f, -0.109f, 0.536f, 0.537f,
+ -0.908f, 0.0f, -0.101f, 0.535f, 0.535f, -0.922f, 0.0f, -0.092f, 0.535f, 0.535f, -0.936f, 0.0f, -0.082f, 0.534f, 0.534f, -0.949f, 0.0f, -0.072f, 0.534f, 0.534f,
+ -0.963f, 0.0f, -0.061f, 0.534f, 0.534f, -0.976f, 0.0f, -0.05f, 0.534f, 0.534f, -0.988f, 0.0f, -0.039f, 0.534f, 0.534f, -1.0f, 0.0f, -0.028f, 0.533f, 0.534f,
+ -1.011f, 0.0f, -0.017f, 0.533f, 0.533f, -1.022f, 0.0f, -0.007f, 0.533f, 0.534f, -1.033f, 0.0f, 0.004f, 0.533f, 0.533f, -1.043f, 0.0f, 0.014f, 0.532f, 0.532f,
+ -1.053f, 0.0f, 0.025f, 0.532f, 0.532f, -1.062f, 0.0f, 0.036f, 0.531f, 0.531f, -1.071f, 0.0f, 0.046f, 0.531f, 0.531f, -1.078f, 0.0f, 0.057f, 0.531f, 0.531f,
+ -1.085f, 0.0f, 0.068f, 0.531f, 0.531f, -1.092f, 0.0f, 0.08f, 0.532f, 0.532f, -1.098f, 0.0f, 0.091f, 0.533f, 0.533f, -1.104f, 0.0f, 0.105f, 0.535f, 0.535f,
+ -1.11f, 0.0f, 0.119f, 0.539f, 0.539f, -1.115f, 0.0f, 0.133f, 0.54f, 0.54f, -1.118f, 0.0f, 0.148f, 0.541f, 0.541f, -1.121f, 0.0f, 0.162f, 0.542f, 0.542f,
+ -1.123f, 0.0f, 0.177f, 0.542f, 0.542f, -1.125f, 0.0f, 0.193f, 0.543f, 0.543f, -1.125f, 0.0f, 0.208f, 0.543f, 0.543f, -1.125f, 0.0f, 0.225f, 0.543f, 0.543f,
+ -1.124f, 0.0f, 0.241f, 0.545f, 0.545f, -1.122f, 0.0f, 0.258f, 0.546f, 0.546f, -1.119f, 0.0f, 0.274f, 0.548f, 0.548f, -1.116f, 0.0f, 0.29f, 0.549f, 0.549f,
+ -1.111f, 0.0f, 0.305f, 0.549f, 0.549f, -1.106f, 0.0f, 0.318f, 0.549f, 0.549f, -1.1f, 0.0f, 0.33f, 0.549f, 0.549f, -1.094f, 0.0f, 0.34f, 0.549f, 0.549f,
+ -1.087f, 0.0f, 0.349f, 0.55f, 0.55f, -1.08f, 0.0f, 0.357f, 0.549f, 0.549f, -1.072f, 0.0f, 0.365f, 0.55f, 0.55f, -1.063f, 0.0f, 0.372f, 0.551f, 0.551f,
+ -1.054f, 0.0f, 0.379f, 0.552f, 0.552f, -1.044f, 0.0f, 0.385f, 0.553f, 0.553f, -1.034f, 0.0f, 0.391f, 0.553f, 0.553f, -1.024f, 0.0f, 0.396f, 0.554f, 0.554f,
+ -1.013f, 0.0f, 0.401f, 0.554f, 0.554f, -1.003f, 0.0f, 0.405f, 0.554f, 0.554f, -0.991f, 0.0f, 0.409f, 0.554f, 0.554f, -0.978f, 0.0f, 0.412f, 0.555f, 0.555f,
+ -0.964f, -0.0f, 0.414f, 0.555f, 0.555f, -0.949f, -0.0f, 0.414f, 0.556f, 0.556f, -0.934f, -0.0f, 0.413f, 0.556f, 0.556f, -0.919f, -0.0f, 0.412f, 0.557f, 0.557f,
+ -0.905f, -0.0f, 0.41f, 0.557f, 0.557f, -0.892f, -0.0f, 0.406f, 0.557f, 0.557f, -0.879f, -0.0f, 0.402f, 0.557f, 0.558f, -0.867f, -0.0f, 0.398f, 0.557f, 0.557f,
+ -0.855f, -0.0f, 0.394f, 0.557f, 0.557f, -0.843f, -0.0f, 0.388f, 0.557f, 0.557f, -0.831f, -0.0f, 0.381f, 0.558f, 0.557f, -0.82f, -0.0f, 0.375f, 0.558f, 0.557f,
+ -0.81f, -0.0f, 0.368f, 0.558f, 0.558f, -0.801f, -0.0f, 0.362f, 0.558f, 0.558f, -0.793f, -0.0f, 0.357f, 0.557f, 0.559f, -0.784f, 0.0f, 0.353f, 0.557f, 0.559f,
+ -0.776f, 0.0f, 0.35f, 0.556f, 0.559f, -0.768f, 0.0f, 0.348f, 0.556f, 0.559f, -0.76f, 0.0f, 0.346f, 0.555f, 0.559f, -0.752f, 0.0f, 0.346f, 0.554f, 0.559f,
+ -0.744f, 0.0f, 0.347f, 0.553f, 0.554f, -0.737f, 0.0f, 0.348f, 0.552f, 0.548f, -0.729f, 0.0f, 0.351f, 0.551f, 0.544f, -0.723f, 0.0f, 0.355f, 0.551f, 0.546f,
+ -0.716f, 0.0f, 0.36f, 0.55f, 0.546f, -0.709f, 0.0f, 0.366f, 0.55f, 0.547f, -0.702f, 0.0f, 0.372f, 0.549f, 0.547f, -0.696f, 0.0f, 0.379f, 0.549f, 0.547f,
+ -0.689f, 0.0f, 0.386f, 0.549f, 0.548f, -0.683f, 0.0f, 0.394f, 0.549f, 0.548f, -0.676f, 0.0f, 0.403f, 0.549f, 0.549f, -0.67f, 0.0f, 0.413f, 0.549f, 0.548f,
+ -0.664f, 0.0f, 0.422f, 0.549f, 0.549f, -0.658f, 0.0f, 0.432f, 0.55f, 0.549f, -0.652f, 0.0f, 0.441f, 0.551f, 0.548f, -0.646f, 0.0f, 0.451f, 0.552f, 0.548f,
+ -0.639f, 0.0f, 0.46f, 0.554f, 0.548f, -0.632f, 0.0f, 0.469f, 0.556f, 0.549f, -0.624f, 0.0f, 0.478f, 0.559f, 0.549f, -0.616f, 0.0f, 0.487f, 0.563f, 0.549f,
+ -0.609f, 0.0f, 0.497f, 0.567f, 0.549f, -0.6f, 0.0f, 0.507f, 0.572f, 0.558f, -0.592f, 0.0f, 0.518f, 0.577f, 0.574f, -0.584f, 0.0f, 0.528f, 0.582f, 0.587f,
+ -0.575f, 0.0f, 0.538f, 0.586f, 0.592f, -0.566f, 0.0f, 0.548f, 0.591f, 0.595f, -0.556f, 0.0f, 0.557f, 0.594f, 0.597f, -0.546f, 0.0f, 0.567f, 0.597f, 0.598f,
+ -0.536f, 0.0f, 0.577f, 0.6f, 0.6f, -0.525f, 0.0f, 0.586f, 0.602f, 0.603f, -0.514f, 0.0f, 0.596f, 0.604f, 0.605f, -0.503f, 0.0f, 0.606f, 0.605f, 0.606f,
+ -0.492f, 0.0f, 0.615f, 0.606f, 0.607f, -0.482f, 0.0f, 0.624f, 0.607f, 0.607f, -0.471f, 0.0f, 0.632f, 0.608f, 0.607f, -0.462f, 0.0f, 0.64f, 0.609f, 0.607f,
+ -0.453f, 0.0f, 0.647f, 0.61f, 0.61f, -0.444f, 0.0f, 0.654f, 0.612f, 0.611f, -0.435f, 0.0f, 0.66f, 0.614f, 0.613f, -0.427f, 0.0f, 0.666f, 0.616f, 0.615f,
+ -0.418f, 0.0f, 0.672f, 0.617f, 0.618f, -0.409f, 0.0f, 0.677f, 0.619f, 0.621f, -0.399f, 0.0f, 0.683f, 0.621f, 0.622f, -0.389f, 0.0f, 0.69f, 0.623f, 0.623f,
+ -0.379f, 0.0f, 0.696f, 0.624f, 0.624f, -0.368f, 0.0f, 0.702f, 0.626f, 0.626f, -0.356f, 0.0f, 0.708f, 0.628f, 0.628f, -0.345f, 0.0f, 0.713f, 0.63f, 0.63f,
+ -0.333f, 0.0f, 0.719f, 0.633f, 0.631f, -0.32f, 0.0f, 0.724f, 0.637f, 0.632f, -0.307f, 0.0f, 0.729f, 0.641f, 0.64f, -0.294f, 0.0f, 0.732f, 0.646f, 0.644f,
+ -0.281f, 0.0f, 0.736f, 0.65f, 0.655f, -0.268f, 0.0f, 0.739f, 0.654f, 0.657f, -0.255f, 0.0f, 0.742f, 0.657f, 0.658f, -0.243f, 0.0f, 0.745f, 0.659f, 0.661f,
+ -0.23f, 0.0f, 0.747f, 0.662f, 0.663f, -0.217f, 0.0f, 0.75f, 0.664f, 0.664f, -0.203f, 0.0f, 0.753f, 0.666f, 0.666f, -0.19f, 0.0f, 0.755f, 0.667f, 0.668f,
+ -0.177f, 0.0f, 0.757f, 0.669f, 0.67f, -0.163f, 0.0f, 0.76f, 0.671f, 0.671f, -0.15f, 0.0f, 0.762f, 0.673f, 0.672f, -0.136f, 0.0f, 0.764f, 0.674f, 0.674f,
+ -0.122f, 0.0f, 0.767f, 0.676f, 0.676f, -0.108f, 0.0f, 0.769f, 0.677f, 0.678f, -0.093f, 0.0f, 0.771f, 0.678f, 0.68f, -0.079f, 0.0f, 0.773f, 0.678f, 0.68f,
+ -0.064f, 0.0f, 0.774f, 0.679f, 0.679f, -0.049f, 0.0f, 0.775f, 0.68f, 0.68f, -0.033f, 0.0f, 0.775f, 0.68f, 0.68f, -0.018f, 0.0f, 0.776f, 0.68f, 0.68f,
+ -0.002f, 0.0f, 0.776f, 0.681f, 0.68f, 0.013f, 0.0f, 0.777f, 0.681f, 0.681f, 0.029f, 0.0f, 0.777f, 0.682f, 0.681f, 0.045f, 0.0f, 0.777f, 0.682f, 0.681f,
+ 0.061f, 0.0f, 0.777f, 0.683f, 0.683f, 0.077f, 0.0f, 0.776f, 0.683f, 0.683f, 0.094f, 0.0f, 0.775f, 0.684f, 0.684f, 0.11f, 0.0f, 0.774f, 0.685f, 0.683f,
+ 0.126f, 0.0f, 0.773f, 0.685f, 0.685f, 0.142f, 0.0f, 0.771f, 0.687f, 0.685f, 0.158f, 0.0f, 0.769f, 0.688f, 0.685f, 0.174f, 0.0f, 0.767f, 0.69f, 0.686f,
+ 0.19f, 0.0f, 0.765f, 0.691f, 0.692f, 0.206f, 0.0f, 0.762f, 0.693f, 0.694f, 0.222f, 0.0f, 0.757f, 0.695f, 0.696f, 0.238f, 0.0f, 0.752f, 0.697f, 0.697f,
+ 0.254f, 0.0f, 0.747f, 0.699f, 0.698f, 0.27f, 0.0f, 0.742f, 0.7f, 0.7f, 0.286f, 0.0f, 0.736f, 0.702f, 0.702f, 0.302f, 0.0f, 0.73f, 0.704f, 0.704f,
+ 0.318f, 0.0f, 0.724f, 0.705f, 0.71f, 0.335f, 0.0f, 0.717f, 0.707f, 0.71f, 0.351f, 0.0f, 0.709f, 0.708f, 0.71f, 0.367f, 0.0f, 0.701f, 0.709f, 0.711f,
+ 0.382f, 0.0f, 0.692f, 0.71f, 0.713f, 0.397f, 0.0f, 0.683f, 0.711f, 0.713f, 0.41f, 0.0f, 0.675f, 0.712f, 0.713f, 0.422f, 0.0f, 0.666f, 0.712f, 0.714f,
+ 0.434f, 0.0f, 0.658f, 0.713f, 0.714f, 0.446f, 0.0f, 0.649f, 0.714f, 0.714f, 0.458f, 0.0f, 0.641f, 0.714f, 0.714f, 0.47f, 0.0f, 0.632f, 0.715f, 0.715f,
+ 0.483f, 0.0f, 0.622f, 0.715f, 0.716f, 0.496f, 0.0f, 0.611f, 0.715f, 0.716f, 0.51f, 0.0f, 0.6f, 0.716f, 0.717f, 0.523f, 0.0f, 0.588f, 0.716f, 0.716f,
+ 0.536f, 0.0f, 0.576f, 0.717f, 0.717f, 0.55f, 0.0f, 0.563f, 0.717f, 0.717f, 0.564f, 0.0f, 0.549f, 0.717f, 0.717f, 0.577f, 0.0f, 0.536f, 0.718f, 0.717f,
+ 0.59f, 0.0f, 0.522f, 0.718f, 0.717f, 0.603f, 0.0f, 0.508f, 0.718f, 0.718f, 0.615f, 0.0f, 0.496f, 0.718f, 0.718f, 0.625f, 0.0f, 0.484f, 0.718f, 0.718f,
+ 0.635f, 0.0f, 0.473f, 0.719f, 0.718f, 0.645f, 0.0f, 0.461f, 0.719f, 0.718f, 0.654f, 0.0f, 0.45f, 0.719f, 0.718f, 0.662f, 0.0f, 0.44f, 0.719f, 0.719f,
+ 0.67f, 0.0f, 0.431f, 0.719f, 0.719f, 0.676f, 0.0f, 0.422f, 0.719f, 0.719f, 0.682f, 0.0f, 0.414f, 0.719f, 0.719f, 0.687f, 0.0f, 0.407f, 0.719f, 0.719f,
+ 0.692f, 0.0f, 0.4f, 0.719f, 0.719f, 0.697f, 0.0f, 0.394f, 0.719f, 0.719f, 0.701f, 0.0f, 0.388f, 0.718f, 0.718f, 0.705f, 0.0f, 0.383f, 0.718f, 0.717f,
+ 0.708f, 0.0f, 0.378f, 0.718f, 0.717f, 0.711f, 0.0f, 0.374f, 0.717f, 0.717f, 0.714f, 0.0f, 0.37f, 0.717f, 0.717f, 0.717f, 0.0f, 0.366f, 0.717f, 0.717f,
+ 0.719f, 0.0f, 0.362f, 0.718f, 0.717f, 0.722f, 0.0f, 0.359f, 0.718f, 0.718f, 0.724f, 0.0f, 0.356f, 0.718f, 0.717f, 0.727f, 0.0f, 0.352f, 0.717f, 0.719f,
+ 0.73f, 0.0f, 0.349f, 0.717f, 0.719f, 0.734f, 0.0f, 0.347f, 0.715f, 0.719f, 0.737f, 0.0f, 0.344f, 0.714f, 0.714f, 0.742f, 0.0f, 0.341f, 0.713f, 0.709f,
+ 0.746f, 0.0f, 0.339f, 0.714f, 0.707f, 0.751f, 0.0f, 0.336f, 0.718f, 0.704f, 0.757f, 0.0f, 0.334f, 0.724f, 0.705f, 0.763f, 0.0f, 0.332f, 0.732f, 0.705f,
+ 0.769f, -0.0f, 0.329f, 0.742f, 0.704f, 0.775f, -0.0f, 0.328f, 0.753f, 0.713f, 0.782f, -0.0f, 0.327f, 0.764f, 0.804f, 0.789f, -0.0f, 0.327f, 0.774f, 0.813f,
+ 0.797f, -0.0f, 0.327f, 0.783f, 0.815f, 0.805f, -0.0f, 0.328f, 0.791f, 0.815f, 0.814f, -0.0f, 0.329f, 0.797f, 0.816f, 0.823f, -0.0f, 0.331f, 0.802f, 0.815f,
+ 0.832f, 0.0f, 0.335f, 0.806f, 0.816f, 0.841f, 0.0f, 0.341f, 0.809f, 0.816f, 0.851f, 0.0f, 0.346f, 0.811f, 0.816f, 0.861f, 0.0f, 0.351f, 0.812f, 0.816f,
+ 0.871f, 0.0f, 0.356f, 0.813f, 0.815f, 0.881f, 0.0f, 0.361f, 0.814f, 0.816f, 0.893f, 0.0f, 0.365f, 0.814f, 0.816f, 0.906f, 0.0f, 0.368f, 0.814f, 0.817f,
+ 0.922f, 0.0f, 0.372f, 0.813f, 0.816f, 0.939f, 0.0f, 0.375f, 0.812f, 0.817f, 0.957f, 0.0f, 0.377f, 0.811f, 0.817f, 0.977f, 0.0f, 0.379f, 0.81f, 0.815f,
+ 0.995f, 0.0f, 0.38f, 0.808f, 0.813f, 1.012f, 0.0f, 0.379f, 0.806f, 0.807f, 1.028f, 0.0f, 0.377f, 0.803f, 0.803f, 1.042f, 0.0f, 0.374f, 0.8f, 0.801f,
+ 1.054f, 0.0f, 0.371f, 0.797f, 0.8f, 1.065f, 0.0f, 0.366f, 0.794f, 0.8f, 1.076f, 0.0f, 0.361f, 0.791f, 0.792f, 1.085f, 0.0f, 0.355f, 0.788f, 0.781f,
+ 1.093f, 0.0f, 0.348f, 0.785f, 0.781f, 1.1f, 0.0f, 0.34f, 0.783f, 0.78f, 1.106f, 0.0f, 0.33f, 0.782f, 0.78f, 1.113f, 0.0f, 0.321f, 0.781f, 0.778f,
+ 1.117f, 0.0f, 0.31f, 0.78f, 0.777f, 1.122f, -0.0f, 0.299f, 0.779f, 0.777f, 1.125f, -0.0f, 0.286f, 0.778f, 0.776f, 1.129f, -0.0f, 0.274f, 0.778f, 0.777f,
+ 1.131f, -0.0f, 0.262f, 0.778f, 0.777f, 1.132f, -0.0f, 0.249f, 0.777f, 0.777f, 1.134f, -0.0f, 0.237f, 0.777f, 0.778f, 1.134f, -0.0f, 0.225f, 0.777f, 0.778f,
+ 1.135f, -0.0f, 0.213f, 0.776f, 0.777f, 1.134f, -0.0f, 0.201f, 0.776f, 0.776f, 1.134f, -0.0f, 0.189f, 0.776f, 0.775f, 1.132f, -0.0f, 0.177f, 0.775f, 0.776f,
+ 1.13f, -0.0f, 0.164f, 0.775f, 0.775f, 1.129f, -0.0f, 0.152f, 0.774f, 0.774f, 1.126f, -0.0f, 0.141f, 0.774f, 0.773f, 1.122f, -0.0f, 0.13f, 0.774f, 0.772f,
+ 1.118f, -0.0f, 0.118f, 0.773f, 0.772f, 1.113f, -0.0f, 0.108f, 0.773f, 0.773f, 1.107f, -0.0f, 0.097f, 0.773f, 0.774f, 1.102f, -0.0f, 0.087f, 0.772f, 0.773f,
+ 1.095f, -0.0f, 0.077f, 0.772f, 0.773f, 1.088f, -0.0f, 0.067f, 0.771f, 0.772f, 1.081f, -0.0f, 0.057f, 0.771f, 0.773f, 1.073f, -0.0f, 0.048f, 0.77f, 0.772f,
+ 1.066f, -0.0f, 0.038f, 0.769f, 0.767f, 1.058f, -0.0f, 0.029f, 0.768f, 0.766f, 1.05f, -0.0f, 0.019f, 0.768f, 0.765f, 1.041f, -0.0f, 0.011f, 0.767f, 0.765f,
+ 1.032f, -0.0f, 0.003f, 0.767f, 0.766f, 1.023f, -0.0f, -0.004f, 0.766f, 0.765f, 1.013f, -0.0f, -0.011f, 0.766f, 0.765f, 1.003f, -0.0f, -0.019f, 0.765f, 0.766f,
+ 0.993f, -0.0f, -0.026f, 0.765f, 0.765f, 0.983f, -0.0f, -0.034f, 0.764f, 0.765f, 0.972f, -0.0f, -0.041f, 0.762f, 0.765f, 0.962f, -0.0f, -0.048f, 0.761f, 0.765f,
+ 0.951f, -0.0f, -0.055f, 0.759f, 0.762f, 0.94f, -0.0f, -0.063f, 0.756f, 0.761f, 0.929f, -0.0f, -0.07f, 0.754f, 0.755f, 0.918f, -0.0f, -0.078f, 0.751f, 0.751f,
+ 0.907f, -0.0f, -0.085f, 0.748f, 0.747f, 0.896f, -0.0f, -0.092f, 0.745f, 0.744f, 0.884f, -0.0f, -0.099f, 0.742f, 0.742f, 0.873f, -0.0f, -0.105f, 0.739f, 0.738f,
+ 0.861f, -0.0f, -0.11f, 0.736f, 0.737f, 0.849f, 0.0f, -0.115f, 0.733f, 0.731f, 0.836f, 0.0f, -0.119f, 0.73f, 0.73f, 0.823f, 0.0f, -0.124f, 0.728f, 0.727f,
+ 0.81f, 0.0f, -0.128f, 0.725f, 0.725f, 0.796f, 0.0f, -0.132f, 0.723f, 0.723f, 0.783f, 0.0f, -0.136f, 0.72f, 0.719f, 0.77f, 0.0f, -0.141f, 0.718f, 0.717f,
+ 0.756f, 0.0f, -0.145f, 0.715f, 0.712f, 0.742f, 0.0f, -0.15f, 0.713f, 0.708f, 0.728f, 0.0f, -0.152f, 0.711f, 0.707f, 0.713f, 0.0f, -0.155f, 0.709f, 0.706f,
+ 0.699f, 0.0f, -0.156f, 0.706f, 0.706f, 0.684f, 0.0f, -0.158f, 0.704f, 0.705f, 0.67f, 0.0f, -0.159f, 0.702f, 0.705f, 0.656f, 0.0f, -0.16f, 0.7f, 0.704f,
+ 0.642f, 0.0f, -0.161f, 0.698f, 0.702f, 0.628f, 0.0f, -0.161f, 0.695f, 0.698f, 0.614f, 0.0f, -0.162f, 0.693f, 0.695f, 0.6f, 0.0f, -0.162f, 0.691f, 0.691f,
+ 0.587f, 0.0f, -0.162f, 0.688f, 0.686f, 0.574f, 0.0f, -0.162f, 0.686f, 0.685f, 0.561f, 0.0f, -0.161f, 0.683f, 0.683f, 0.548f, 0.0f, -0.161f, 0.681f, 0.683f,
+ 0.535f, 0.0f, -0.161f, 0.678f, 0.678f, 0.523f, 0.0f, -0.16f, 0.676f, 0.676f, 0.512f, 0.0f, -0.16f, 0.673f, 0.674f, 0.501f, 0.0f, -0.16f, 0.671f, 0.67f,
+ 0.49f, 0.0f, -0.16f, 0.668f, 0.668f, 0.48f, 0.0f, -0.161f, 0.666f, 0.663f, 0.469f, 0.0f, -0.162f, 0.665f, 0.66f, 0.458f, 0.0f, -0.165f, 0.663f, 0.66f,
+ 0.447f, 0.0f, -0.167f, 0.662f, 0.659f, 0.437f, 0.0f, -0.171f, 0.661f, 0.659f, 0.426f, 0.0f, -0.175f, 0.66f, 0.659f, 0.415f, 0.0f, -0.18f, 0.66f, 0.659f,
+ 0.404f, 0.0f, -0.185f, 0.659f, 0.659f, 0.393f, 0.0f, -0.191f, 0.659f, 0.657f, 0.383f, 0.0f, -0.196f, 0.659f, 0.657f, 0.373f, 0.0f, -0.202f, 0.658f, 0.659f,
+ 0.363f, -0.0f, -0.208f, 0.658f, 0.658f, 0.353f, -0.0f, -0.215f, 0.658f, 0.659f, 0.344f, -0.0f, -0.223f, 0.658f, 0.659f, 0.336f, -0.0f, -0.23f, 0.658f, 0.659f,
+ 0.327f, -0.0f, -0.238f, 0.658f, 0.658f, 0.319f, -0.0f, -0.245f, 0.657f, 0.657f, 0.312f, -0.0f, -0.253f, 0.657f, 0.656f, 0.305f, -0.0f, -0.261f, 0.656f, 0.658f,
+ 0.299f, -0.0f, -0.269f, 0.655f, 0.658f, 0.293f, 0.0f, -0.278f, 0.653f, 0.657f, 0.288f, 0.0f, -0.287f, 0.65f, 0.657f, 0.283f, 0.0f, -0.295f, 0.646f, 0.656f,
+ 0.279f, 0.0f, -0.304f, 0.642f, 0.655f, 0.275f, 0.0f, -0.313f, 0.637f, 0.642f, 0.271f, 0.0f, -0.322f, 0.633f, 0.637f, 0.268f, 0.0f, -0.331f, 0.628f, 0.609f,
+ 0.265f, 0.0f, -0.341f, 0.624f, 0.607f, 0.263f, 0.0f, -0.35f, 0.62f, 0.608f, 0.261f, 0.0f, -0.359f, 0.617f, 0.608f, 0.259f, 0.0f, -0.369f, 0.614f, 0.607f,
+ 0.258f, 0.0f, -0.379f, 0.612f, 0.606f, 0.257f, 0.0f, -0.389f, 0.61f, 0.606f, 0.258f, 0.0f, -0.399f, 0.609f, 0.605f, 0.258f, 0.0f, -0.41f, 0.608f, 0.604f,
+ 0.26f, 0.0f, -0.421f, 0.608f, 0.606f, 0.263f, 0.0f, -0.431f, 0.607f, 0.606f, 0.266f, 0.0f, -0.441f, 0.607f, 0.606f, 0.27f, 0.0f, -0.452f, 0.606f, 0.607f,
+ 0.274f, 0.0f, -0.463f, 0.606f, 0.607f, 0.279f, 0.0f, -0.475f, 0.605f, 0.607f, 0.283f, 0.0f, -0.487f, 0.604f, 0.607f, 0.288f, 0.0f, -0.498f, 0.603f, 0.607f,
+ 0.293f, 0.0f, -0.511f, 0.601f, 0.607f, 0.297f, 0.0f, -0.523f, 0.598f, 0.606f, 0.301f, 0.0f, -0.536f, 0.595f, 0.605f, 0.305f, 0.0f, -0.549f, 0.591f, 0.602f,
+ 0.309f, 0.0f, -0.562f, 0.588f, 0.597f, 0.312f, 0.0f, -0.576f, 0.583f, 0.585f, 0.315f, 0.0f, -0.59f, 0.579f, 0.577f, 0.318f, 0.0f, -0.604f, 0.574f, 0.576f,
+ 0.321f, 0.0f, -0.618f, 0.569f, 0.57f, 0.323f, 0.0f, -0.633f, 0.564f, 0.564f, 0.326f, 0.0f, -0.647f, 0.559f, 0.554f, 0.328f, 0.0f, -0.663f, 0.555f, 0.549f,
+ 0.33f, 0.0f, -0.678f, 0.551f, 0.546f, 0.332f, 0.0f, -0.693f, 0.547f, 0.543f, 0.334f, 0.0f, -0.709f, 0.544f, 0.543f, 0.336f, 0.0f, -0.726f, 0.541f, 0.541f,
+ 0.338f, 0.0f, -0.742f, 0.538f, 0.54f, 0.338f, 0.0f, -0.758f, 0.536f, 0.538f, 0.338f, 0.0f, -0.773f, 0.534f, 0.53f, 0.337f, 0.0f, -0.787f, 0.532f, 0.528f,
+ 0.337f, 0.0f, -0.801f, 0.53f, 0.528f, 0.336f, 0.0f, -0.814f, 0.529f, 0.528f, 0.334f, 0.0f, -0.827f, 0.527f, 0.528f, 0.333f, 0.0f, -0.84f, 0.525f, 0.529f,
+ 0.331f, 0.0f, -0.853f, 0.523f, 0.529f, 0.328f, 0.0f, -0.866f, 0.521f, 0.528f, 0.324f, 0.0f, -0.877f, 0.519f, 0.516f, 0.32f, 0.0f, -0.889f, 0.516f, 0.515f,
+ 0.315f, 0.0f, -0.9f, 0.513f, 0.515f, 0.31f, 0.0f, -0.91f, 0.51f, 0.514f, 0.304f, 0.0f, -0.921f, 0.507f, 0.513f, 0.297f, 0.0f, -0.931f, 0.505f, 0.507f,
+ 0.289f, 0.0f, -0.94f, 0.502f, 0.498f, 0.281f, 0.0f, -0.948f, 0.499f, 0.494f, 0.272f, 0.0f, -0.956f, 0.497f, 0.491f, 0.262f, 0.0f, -0.963f, 0.495f, 0.49f,
+ 0.253f, 0.0f, -0.969f, 0.494f, 0.491f, 0.242f, 0.0f, -0.975f, 0.493f, 0.491f, 0.231f, 0.0f, -0.98f, 0.492f, 0.49f, 0.22f, 0.0f, -0.986f, 0.491f, 0.489f,
+ 0.208f, 0.0f, -0.99f, 0.491f, 0.49f, 0.195f, 0.0f, -0.994f, 0.491f, 0.491f, 0.181f, 0.0f, -0.998f, 0.491f, 0.491f, 0.168f, 0.0f, -1.001f, 0.491f, 0.492f,
+ 0.154f, 0.0f, -1.005f, 0.491f, 0.492f, 0.141f, 0.0f, -1.008f, 0.492f, 0.492f, 0.126f, 0.0f, -1.01f, 0.492f, 0.492f, 0.112f, 0.0f, -1.011f, 0.492f, 0.492f,
+ 0.097f, 0.0f, -1.013f, 0.492f, 0.492f, 0.081f, 0.0f, -1.013f, 0.492f, 0.492f, 0.066f, 0.0f, -1.014f, 0.493f, 0.493f, 0.05f, 0.0f, -1.014f, 0.493f, 0.494f,
+ 0.035f, 0.0f, -1.014f, 0.493f, 0.494f, 0.019f, 0.0f, -1.013f, 0.493f, 0.494f, 0.004f, 0.0f, -1.012f, 0.493f, 0.494f, -0.011f, 0.0f, -1.011f, 0.493f, 0.493f,
+ -0.026f, 0.0f, -1.01f, 0.492f, 0.493f, -0.041f, 0.0f, -1.008f, 0.492f, 0.492f, -0.056f, 0.0f, -1.006f, 0.492f, 0.492f, -0.07f, 0.0f, -1.004f, 0.491f, 0.492f,
+ -0.084f, 0.0f, -1.001f, 0.491f, 0.492f, -0.098f, 0.0f, -0.999f, 0.491f, 0.491f, -0.112f, 0.0f, -0.995f, 0.491f, 0.49f, -0.125f, 0.0f, -0.992f, 0.49f, 0.49f,
+ -0.138f, 0.0f, -0.987f, 0.49f, 0.491f, -0.15f, 0.0f, -0.983f, 0.49f, 0.49f, -0.162f, 0.0f, -0.978f, 0.49f, 0.49f, -0.174f, 0.0f, -0.973f, 0.489f, 0.489f,
+ -0.185f, 0.0f, -0.967f, 0.489f, 0.488f, -0.196f, 0.0f, -0.961f, 0.489f, 0.489f, -0.207f, 0.0f, -0.955f, 0.489f, 0.489f, -0.218f, 0.0f, -0.949f, 0.489f, 0.49f,
+ -0.229f, 0.0f, -0.943f, 0.489f, 0.489f, -0.24f, 0.0f, -0.936f, 0.489f, 0.489f, -0.25f, 0.0f, -0.929f, 0.489f, 0.489f, -0.261f, 0.0f, -0.922f, 0.489f, 0.489f,
+ -0.271f, 0.0f, -0.914f, 0.489f, 0.49f, -0.28f, 0.0f, -0.907f, 0.49f, 0.49f, -0.289f, 0.0f, -0.898f, 0.49f, 0.489f, -0.298f, 0.0f, -0.89f, 0.49f, 0.489f,
+ -0.306f, 0.0f, -0.882f, 0.49f, 0.49f, -0.314f, 0.0f, -0.875f, 0.491f, 0.489f, -0.322f, 0.0f, -0.866f, 0.492f, 0.489f, -0.328f, 0.0f, -0.857f, 0.492f, 0.489f,
+ -0.333f, 0.0f, -0.847f, 0.493f, 0.49f, -0.336f, 0.0f, -0.836f, 0.494f, 0.488f, -0.338f, 0.0f, -0.824f, 0.496f, 0.49f, -0.338f, 0.0f, -0.811f, 0.497f, 0.49f,
+ -0.338f, 0.0f, -0.798f, 0.499f, 0.491f, -0.337f, 0.0f, -0.785f, 0.501f, 0.497f, -0.337f, 0.0f, -0.772f, 0.503f, 0.5f, -0.337f, 0.0f, -0.759f, 0.505f, 0.504f,
+ -0.336f, -0.0f, -0.746f, 0.507f, 0.505f, -0.336f, -0.0f, -0.733f, 0.51f, 0.51f, -0.335f, -0.0f, -0.719f, 0.512f, 0.513f, -0.334f, -0.0f, -0.706f, 0.515f, 0.515f,
+ -0.333f, -0.0f, -0.692f, 0.518f, 0.516f, -0.332f, -0.0f, -0.678f, 0.52f, 0.522f, -0.331f, -0.0f, -0.665f, 0.523f, 0.523f, -0.329f, -0.0f, -0.651f, 0.525f, 0.528f,
+ -0.327f, -0.0f, -0.637f, 0.528f, 0.53f, -0.325f, -0.0f, -0.624f, 0.53f, 0.532f, -0.322f, -0.0f, -0.61f, 0.532f, 0.534f, -0.319f, -0.0f, -0.597f, 0.535f, 0.535f,
+ -0.316f, -0.0f, -0.584f, 0.537f, 0.538f, -0.313f, -0.0f, -0.57f, 0.539f, 0.54f, -0.31f, -0.0f, -0.557f, 0.541f, 0.542f, -0.307f, -0.0f, -0.544f, 0.542f, 0.545f,
+ -0.303f, -0.0f, -0.531f, 0.544f, 0.546f, -0.3f, -0.0f, -0.519f, 0.546f, 0.549f, -0.298f, -0.0f, -0.506f, 0.547f, 0.549f, -0.295f, -0.0f, -0.494f, 0.548f, 0.549f,
+ -0.292f, -0.0f, -0.482f, 0.549f, 0.55f, -0.29f, -0.0f, -0.47f, 0.55f, 0.552f, -0.287f, -0.0f, -0.459f, 0.551f, 0.552f, -0.285f, -0.0f, -0.447f, 0.551f, 0.552f,
+ -0.284f, -0.0f, -0.436f, 0.552f, 0.552f, -0.282f, -0.0f, -0.425f, 0.552f, 0.553f, -0.281f, -0.0f, -0.413f, 0.553f, 0.553f, -0.28f, -0.0f, -0.402f, 0.553f, 0.553f,
+ -0.28f, -0.0f, -0.392f, 0.553f, 0.553f, -0.281f, -0.0f, -0.381f, 0.554f, 0.553f, -0.283f, -0.0f, -0.369f, 0.554f, 0.554f, -0.286f, -0.0f, -0.359f, 0.554f, 0.554f,
+ -0.289f, -0.0f, -0.348f, 0.555f, 0.554f, -0.294f, -0.0f, -0.337f, 0.555f, 0.555f, -0.299f, -0.0f, -0.327f, 0.555f, 0.554f, -0.305f, -0.0f, -0.317f, 0.556f, 0.555f,
+ -0.312f, -0.0f, -0.307f, 0.556f, 0.555f, -0.319f, -0.0f, -0.297f, 0.556f, 0.557f, -0.326f, 0.0f, -0.287f, 0.557f, 0.558f, -0.334f, 0.0f, -0.278f, 0.557f, 0.557f,
+ -0.341f, 0.0f, -0.268f, 0.557f, 0.558f, -0.349f, 0.0f, -0.259f, 0.558f, 0.558f, -0.359f, 0.0f, -0.251f, 0.558f, 0.558f, -0.368f, 0.0f, -0.243f, 0.558f, 0.558f,
+ -0.378f, 0.0f, -0.235f, 0.558f, 0.559f, -0.388f, 0.0f, -0.228f, 0.558f, 0.558f, -0.398f, 0.0f, -0.221f, 0.559f, 0.559f, -0.408f, 0.0f, -0.214f, 0.559f, 0.559f,
+ -0.418f, 0.0f, -0.208f, 0.559f, 0.559f, -0.427f, 0.0f, -0.202f, 0.559f, 0.558f, -0.436f, 0.0f, -0.196f, 0.559f, 0.559f, -0.445f, 0.0f, -0.191f, 0.559f, 0.559f,
+ -0.453f, 0.0f, -0.187f, 0.558f, 0.559f, -0.462f, 0.0f, -0.183f, 0.558f, 0.558f, -0.469f, 0.0f, -0.18f, 0.558f, 0.558f, -0.477f, 0.0f, -0.176f, 0.558f, 0.558f,
+ -0.484f, 0.0f, -0.174f, 0.557f, 0.558f, -0.493f, 0.0f, -0.17f, 0.555f, 0.559f,
+};
+
+
+static const float data1[136 * GP_PRIM_DATABUF_SIZE] = {
+ -0.369f, 0.0f, -0.048f, 0.065f, 0.065f, -0.378f, 0.0f, -0.046f, 0.239f, 0.293f, -0.383f, 0.0f, -0.044f, 0.316f, 0.339f, -0.39f, 0.0f, -0.041f, 0.348f, 0.355f,
+ -0.398f, 0.0f, -0.038f, 0.364f, 0.368f, -0.405f, 0.0f, -0.035f, 0.373f, 0.374f, -0.413f, 0.0f, -0.031f, 0.381f, 0.381f, -0.421f, 0.0f, -0.026f, 0.388f, 0.391f,
+ -0.429f, 0.0f, -0.02f, 0.392f, 0.394f, -0.437f, 0.0f, -0.014f, 0.395f, 0.396f, -0.445f, 0.0f, -0.008f, 0.397f, 0.397f, -0.453f, 0.0f, -0.001f, 0.399f, 0.4f,
+ -0.461f, 0.0f, 0.007f, 0.401f, 0.401f, -0.468f, -0.0f, 0.016f, 0.404f, 0.404f, -0.474f, 0.0f, 0.023f, 0.406f, 0.407f, -0.479f, 0.0f, 0.03f, 0.409f, 0.409f,
+ -0.485f, 0.0f, 0.039f, 0.412f, 0.412f, -0.49f, 0.0f, 0.048f, 0.415f, 0.415f, -0.495f, 0.0f, 0.057f, 0.417f, 0.417f, -0.499f, 0.0f, 0.068f, 0.42f, 0.421f,
+ -0.503f, 0.0f, 0.079f, 0.421f, 0.421f, -0.507f, -0.0f, 0.091f, 0.423f, 0.423f, -0.51f, -0.0f, 0.102f, 0.424f, 0.424f, -0.513f, -0.0f, 0.112f, 0.424f, 0.425f,
+ -0.515f, -0.0f, 0.123f, 0.425f, 0.425f, -0.517f, -0.0f, 0.135f, 0.425f, 0.425f, -0.518f, -0.0f, 0.146f, 0.426f, 0.425f, -0.519f, -0.0f, 0.158f, 0.426f, 0.425f,
+ -0.52f, -0.0f, 0.169f, 0.426f, 0.426f, -0.52f, -0.0f, 0.181f, 0.427f, 0.427f, -0.519f, -0.0f, 0.192f, 0.427f, 0.427f, -0.518f, -0.0f, 0.203f, 0.427f, 0.427f,
+ -0.517f, -0.0f, 0.213f, 0.427f, 0.428f, -0.515f, -0.0f, 0.222f, 0.428f, 0.427f, -0.513f, -0.0f, 0.232f, 0.428f, 0.427f, -0.51f, -0.0f, 0.241f, 0.429f, 0.427f,
+ -0.508f, -0.0f, 0.25f, 0.43f, 0.428f, -0.505f, -0.0f, 0.259f, 0.431f, 0.431f, -0.501f, -0.0f, 0.267f, 0.431f, 0.432f, -0.497f, -0.0f, 0.276f, 0.432f, 0.433f,
+ -0.493f, -0.0f, 0.284f, 0.433f, 0.433f, -0.488f, -0.0f, 0.293f, 0.434f, 0.434f, -0.484f, -0.0f, 0.301f, 0.434f, 0.435f, -0.479f, -0.0f, 0.308f, 0.435f, 0.436f,
+ -0.474f, -0.0f, 0.316f, 0.435f, 0.435f, -0.468f, -0.0f, 0.322f, 0.436f, 0.436f, -0.463f, -0.0f, 0.329f, 0.436f, 0.436f, -0.457f, -0.0f, 0.335f, 0.436f, 0.436f,
+ -0.451f, -0.0f, 0.341f, 0.437f, 0.436f, -0.445f, -0.0f, 0.347f, 0.438f, 0.437f, -0.438f, -0.0f, 0.352f, 0.44f, 0.437f, -0.432f, -0.0f, 0.357f, 0.442f, 0.441f,
+ -0.426f, 0.0f, 0.362f, 0.444f, 0.446f, -0.419f, 0.0f, 0.366f, 0.445f, 0.447f, -0.413f, 0.0f, 0.369f, 0.446f, 0.447f, -0.407f, 0.0f, 0.373f, 0.446f, 0.447f,
+ -0.401f, 0.0f, 0.376f, 0.447f, 0.447f, -0.395f, 0.0f, 0.378f, 0.447f, 0.448f, -0.388f, 0.0f, 0.381f, 0.447f, 0.448f, -0.382f, 0.0f, 0.383f, 0.448f, 0.448f,
+ -0.375f, 0.0f, 0.384f, 0.448f, 0.448f, -0.369f, 0.0f, 0.386f, 0.448f, 0.448f, -0.362f, 0.0f, 0.387f, 0.448f, 0.448f, -0.355f, 0.0f, 0.388f, 0.448f, 0.448f,
+ -0.348f, 0.0f, 0.388f, 0.448f, 0.448f, -0.341f, 0.0f, 0.387f, 0.448f, 0.449f, -0.334f, 0.0f, 0.387f, 0.448f, 0.448f, -0.327f, 0.0f, 0.386f, 0.448f, 0.449f,
+ -0.32f, 0.0f, 0.384f, 0.449f, 0.449f, -0.313f, 0.0f, 0.382f, 0.449f, 0.449f, -0.307f, 0.0f, 0.38f, 0.449f, 0.449f, -0.3f, 0.0f, 0.377f, 0.449f, 0.45f,
+ -0.294f, 0.0f, 0.375f, 0.45f, 0.45f, -0.288f, -0.0f, 0.372f, 0.45f, 0.45f, -0.282f, -0.0f, 0.368f, 0.45f, 0.451f, -0.276f, -0.0f, 0.365f, 0.45f, 0.451f,
+ -0.27f, -0.0f, 0.361f, 0.45f, 0.451f, -0.264f, -0.0f, 0.357f, 0.45f, 0.451f, -0.258f, -0.0f, 0.352f, 0.45f, 0.45f, -0.251f, -0.0f, 0.347f, 0.45f, 0.451f,
+ -0.245f, -0.0f, 0.341f, 0.451f, 0.451f, -0.24f, -0.0f, 0.335f, 0.451f, 0.451f, -0.234f, -0.0f, 0.329f, 0.451f, 0.451f, -0.228f, -0.0f, 0.323f, 0.452f, 0.452f,
+ -0.223f, -0.0f, 0.316f, 0.452f, 0.453f, -0.218f, -0.0f, 0.309f, 0.452f, 0.453f, -0.213f, -0.0f, 0.301f, 0.453f, 0.453f, -0.208f, -0.0f, 0.294f, 0.453f, 0.453f,
+ -0.204f, -0.0f, 0.286f, 0.453f, 0.453f, -0.2f, -0.0f, 0.277f, 0.453f, 0.454f, -0.196f, -0.0f, 0.269f, 0.453f, 0.454f, -0.192f, -0.0f, 0.26f, 0.454f, 0.454f,
+ -0.189f, -0.0f, 0.25f, 0.454f, 0.454f, -0.186f, -0.0f, 0.241f, 0.454f, 0.455f, -0.183f, -0.0f, 0.231f, 0.454f, 0.455f, -0.181f, -0.0f, 0.221f, 0.454f, 0.455f,
+ -0.179f, -0.0f, 0.209f, 0.455f, 0.455f, -0.177f, -0.0f, 0.197f, 0.455f, 0.455f, -0.176f, -0.0f, 0.184f, 0.455f, 0.455f, -0.176f, -0.0f, 0.171f, 0.455f, 0.456f,
+ -0.176f, -0.0f, 0.158f, 0.455f, 0.456f, -0.177f, -0.0f, 0.145f, 0.455f, 0.456f, -0.178f, -0.0f, 0.132f, 0.455f, 0.456f, -0.18f, -0.0f, 0.12f, 0.456f, 0.456f,
+ -0.182f, -0.0f, 0.108f, 0.456f, 0.456f, -0.185f, -0.0f, 0.097f, 0.456f, 0.456f, -0.188f, -0.0f, 0.086f, 0.456f, 0.457f, -0.191f, -0.0f, 0.076f, 0.456f, 0.457f,
+ -0.194f, -0.0f, 0.067f, 0.457f, 0.457f, -0.198f, -0.0f, 0.058f, 0.457f, 0.457f, -0.202f, -0.0f, 0.05f, 0.457f, 0.457f, -0.206f, -0.0f, 0.042f, 0.457f, 0.457f,
+ -0.21f, -0.0f, 0.034f, 0.458f, 0.457f, -0.215f, -0.0f, 0.027f, 0.458f, 0.457f, -0.22f, -0.0f, 0.02f, 0.458f, 0.458f, -0.225f, -0.0f, 0.014f, 0.458f, 0.458f,
+ -0.23f, -0.0f, 0.007f, 0.458f, 0.458f, -0.235f, -0.0f, 0.002f, 0.459f, 0.458f, -0.24f, -0.0f, -0.004f, 0.459f, 0.458f, -0.246f, -0.0f, -0.009f, 0.46f, 0.459f,
+ -0.251f, 0.0f, -0.013f, 0.464f, 0.463f, -0.257f, 0.0f, -0.018f, 0.467f, 0.468f, -0.262f, 0.0f, -0.022f, 0.469f, 0.469f, -0.268f, 0.0f, -0.026f, 0.471f, 0.47f,
+ -0.274f, 0.0f, -0.029f, 0.477f, 0.478f, -0.28f, 0.0f, -0.033f, 0.478f, 0.478f, -0.286f, 0.0f, -0.036f, 0.478f, 0.478f, -0.292f, 0.0f, -0.038f, 0.479f, 0.479f,
+ -0.298f, 0.0f, -0.041f, 0.48f, 0.48f, -0.305f, 0.0f, -0.043f, 0.48f, 0.48f, -0.311f, 0.0f, -0.045f, 0.482f, 0.482f, -0.318f, 0.0f, -0.047f, 0.482f, 0.482f,
+ -0.324f, 0.0f, -0.048f, 0.482f, 0.482f, -0.331f, 0.0f, -0.049f, 0.48f, 0.482f, -0.336f, 0.0f, -0.05f, 0.457f, 0.485f, -0.344f, 0.0f, -0.05f, 0.32f, 0.32f,
+};
+
+static const float data2[2 * GP_PRIM_DATABUF_SIZE] = {
+ -0.512f, 0.0f, -0.168f, 0.545f, 0.557f, -0.521f, 0.0f, -0.167f, 0.535f, 0.558f,
+};
+
+static const float data3[1 * GP_PRIM_DATABUF_SIZE] = {
+ -1.014f, 0.0f, 0.186f, 0.0f, 0.003f,
+};
+
+static const float data4[1 * GP_PRIM_DATABUF_SIZE] = {
+ -1.014f, 0.0f, 0.186f, 0.02f, 0.02f,
+};
+
+static const float data5[48 * GP_PRIM_DATABUF_SIZE] = {
+ -1.014f, 0.0f, 0.187f, 0.066f, 0.066f, -1.013f, 0.0f, 0.2f, 0.222f, 0.356f, -1.01f, 0.0f, 0.208f, 0.295f, 0.404f, -1.006f, 0.0f, 0.218f, 0.354f, 0.431f,
+ -1.001f, 0.0f, 0.226f, 0.392f, 0.445f, -0.994f, 0.0f, 0.233f, 0.418f, 0.453f, -0.987f, 0.0f, 0.238f, 0.437f, 0.457f, -0.979f, 0.0f, 0.242f, 0.45f, 0.47f,
+ -0.97f, 0.0f, 0.245f, 0.459f, 0.473f, -0.96f, -0.0f, 0.246f, 0.465f, 0.474f, -0.951f, -0.0f, 0.245f, 0.469f, 0.475f, -0.942f, 0.0f, 0.242f, 0.471f, 0.473f,
+ -0.932f, 0.0f, 0.239f, 0.472f, 0.474f, -0.924f, 0.0f, 0.234f, 0.471f, 0.474f, -0.915f, 0.0f, 0.228f, 0.469f, 0.474f, -0.906f, 0.0f, 0.22f, 0.464f, 0.47f,
+ -0.898f, 0.0f, 0.212f, 0.458f, 0.46f, -0.89f, 0.0f, 0.203f, 0.451f, 0.453f, -0.882f, 0.0f, 0.193f, 0.443f, 0.443f, -0.875f, 0.0f, 0.182f, 0.435f, 0.437f,
+ -0.869f, 0.0f, 0.172f, 0.426f, 0.428f, -0.863f, 0.0f, 0.161f, 0.417f, 0.415f, -0.858f, 0.0f, 0.148f, 0.409f, 0.41f, -0.854f, 0.0f, 0.137f, 0.399f, 0.399f,
+ -0.85f, 0.0f, 0.126f, 0.39f, 0.392f, -0.847f, 0.0f, 0.116f, 0.379f, 0.386f, -0.846f, 0.0f, 0.109f, 0.369f, 0.371f, -0.846f, 0.0f, 0.104f, 0.361f, 0.357f,
+ -0.847f, 0.0f, 0.101f, 0.355f, 0.339f, -0.849f, 0.0f, 0.101f, 0.353f, 0.334f, -0.853f, 0.0f, 0.103f, 0.354f, 0.345f, -0.859f, 0.0f, 0.108f, 0.357f, 0.35f,
+ -0.865f, 0.0f, 0.116f, 0.363f, 0.365f, -0.873f, 0.0f, 0.126f, 0.369f, 0.375f, -0.881f, 0.0f, 0.137f, 0.375f, 0.379f, -0.89f, 0.0f, 0.149f, 0.381f, 0.38f,
+ -0.899f, 0.0f, 0.159f, 0.387f, 0.385f, -0.908f, 0.0f, 0.168f, 0.394f, 0.394f, -0.919f, 0.0f, 0.177f, 0.401f, 0.398f, -0.932f, 0.0f, 0.184f, 0.409f, 0.404f,
+ -0.945f, 0.0f, 0.191f, 0.418f, 0.415f, -0.958f, 0.0f, 0.195f, 0.427f, 0.431f, -0.969f, 0.0f, 0.197f, 0.434f, 0.443f, -0.979f, 0.0f, 0.197f, 0.436f, 0.445f,
+ -0.987f, 0.0f, 0.195f, 0.428f, 0.463f, -0.995f, 0.0f, 0.192f, 0.398f, 0.46f, -1.001f, 0.0f, 0.189f, 0.345f, 0.465f, -1.01f, 0.0f, 0.183f, 0.236f, 0.236f,
+};
+
+static const float data6[47 * GP_PRIM_DATABUF_SIZE] = {
+ 0.022f, 0.0f, -0.353f, 0.125f, 0.125f, 0.012f, 0.0f, -0.352f, 0.175f, 0.288f, 0.004f, 0.0f, -0.352f, 0.206f, 0.313f, -0.006f, 0.0f, -0.352f, 0.241f, 0.323f,
+ -0.017f, 0.0f, -0.352f, 0.27f, 0.33f, -0.029f, 0.0f, -0.351f, 0.295f, 0.334f, -0.041f, 0.0f, -0.349f, 0.314f, 0.337f, -0.052f, 0.0f, -0.344f, 0.327f, 0.341f,
+ -0.063f, 0.0f, -0.337f, 0.336f, 0.344f, -0.072f, 0.0f, -0.329f, 0.341f, 0.345f, -0.081f, 0.0f, -0.32f, 0.345f, 0.345f, -0.088f, 0.0f, -0.311f, 0.348f, 0.345f,
+ -0.093f, 0.0f, -0.303f, 0.352f, 0.347f, -0.098f, 0.0f, -0.295f, 0.356f, 0.352f, -0.101f, 0.0f, -0.287f, 0.361f, 0.357f, -0.102f, 0.0f, -0.279f, 0.367f, 0.364f,
+ -0.103f, 0.0f, -0.271f, 0.373f, 0.378f, -0.102f, 0.0f, -0.263f, 0.379f, 0.382f, -0.1f, 0.0f, -0.255f, 0.383f, 0.389f, -0.098f, 0.0f, -0.247f, 0.387f, 0.391f,
+ -0.094f, 0.0f, -0.24f, 0.389f, 0.393f, -0.09f, 0.0f, -0.233f, 0.391f, 0.393f, -0.086f, 0.0f, -0.227f, 0.392f, 0.393f, -0.082f, 0.0f, -0.222f, 0.393f, 0.393f,
+ -0.078f, 0.0f, -0.219f, 0.394f, 0.393f, -0.075f, 0.0f, -0.217f, 0.397f, 0.393f, -0.072f, 0.0f, -0.217f, 0.4f, 0.393f, -0.07f, 0.0f, -0.219f, 0.402f, 0.408f,
+ -0.069f, 0.0f, -0.222f, 0.404f, 0.408f, -0.069f, 0.0f, -0.228f, 0.406f, 0.409f, -0.069f, 0.0f, -0.234f, 0.407f, 0.409f, -0.07f, 0.0f, -0.241f, 0.408f, 0.409f,
+ -0.07f, 0.0f, -0.248f, 0.408f, 0.409f, -0.07f, 0.0f, -0.256f, 0.409f, 0.409f, -0.07f, 0.0f, -0.263f, 0.409f, 0.41f, -0.069f, 0.0f, -0.271f, 0.41f, 0.411f,
+ -0.068f, 0.0f, -0.279f, 0.41f, 0.411f, -0.065f, 0.0f, -0.287f, 0.41f, 0.411f, -0.062f, 0.0f, -0.295f, 0.409f, 0.411f, -0.057f, 0.0f, -0.303f, 0.409f, 0.409f,
+ -0.052f, 0.0f, -0.31f, 0.408f, 0.409f, -0.047f, 0.0f, -0.318f, 0.407f, 0.408f, -0.041f, 0.0f, -0.324f, 0.406f, 0.407f, -0.035f, 0.0f, -0.329f, 0.403f, 0.407f,
+ -0.027f, 0.0f, -0.333f, 0.4f, 0.408f, -0.021f, 0.0f, -0.336f, 0.398f, 0.403f, -0.012f, 0.0f, -0.339f, 0.393f, 0.393f,
+};
+
+static const float data7[162 * GP_PRIM_DATABUF_SIZE] = {
+ -0.291f, 0.0f, -0.34f, 0.093f, 0.093f, -0.289f, -0.0f, -0.35f, 0.149f, 0.176f, -0.287f, -0.0f, -0.357f, 0.182f, 0.242f, -0.284f, -0.0f, -0.365f, 0.215f, 0.257f,
+ -0.281f, -0.0f, -0.374f, 0.242f, 0.266f, -0.278f, -0.0f, -0.384f, 0.266f, 0.287f, -0.275f, -0.0f, -0.394f, 0.285f, 0.304f, -0.271f, 0.0f, -0.405f, 0.302f, 0.316f,
+ -0.267f, 0.0f, -0.417f, 0.317f, 0.326f, -0.263f, 0.0f, -0.429f, 0.33f, 0.337f, -0.259f, 0.0f, -0.442f, 0.342f, 0.346f, -0.256f, 0.0f, -0.454f, 0.354f, 0.351f,
+ -0.253f, 0.0f, -0.467f, 0.365f, 0.362f, -0.251f, 0.0f, -0.48f, 0.376f, 0.38f, -0.249f, -0.0f, -0.493f, 0.386f, 0.391f, -0.247f, -0.0f, -0.505f, 0.394f, 0.396f,
+ -0.246f, -0.0f, -0.518f, 0.401f, 0.405f, -0.245f, 0.0f, -0.53f, 0.408f, 0.409f, -0.245f, 0.0f, -0.542f, 0.415f, 0.413f, -0.245f, 0.0f, -0.554f, 0.421f, 0.42f,
+ -0.245f, 0.0f, -0.565f, 0.426f, 0.43f, -0.246f, 0.0f, -0.575f, 0.43f, 0.433f, -0.246f, -0.0f, -0.585f, 0.432f, 0.435f, -0.247f, -0.0f, -0.594f, 0.434f, 0.436f,
+ -0.247f, -0.0f, -0.603f, 0.435f, 0.436f, -0.248f, -0.0f, -0.612f, 0.436f, 0.436f, -0.25f, -0.0f, -0.621f, 0.437f, 0.438f, -0.252f, -0.0f, -0.631f, 0.437f, 0.438f,
+ -0.254f, -0.0f, -0.642f, 0.438f, 0.438f, -0.255f, 0.0f, -0.653f, 0.438f, 0.438f, -0.258f, 0.0f, -0.664f, 0.438f, 0.439f, -0.26f, 0.0f, -0.674f, 0.439f, 0.439f,
+ -0.261f, 0.0f, -0.685f, 0.439f, 0.439f, -0.262f, 0.0f, -0.696f, 0.439f, 0.439f, -0.264f, 0.0f, -0.706f, 0.439f, 0.439f, -0.265f, 0.0f, -0.717f, 0.439f, 0.439f,
+ -0.265f, 0.0f, -0.727f, 0.438f, 0.439f, -0.266f, 0.0f, -0.738f, 0.437f, 0.439f, -0.266f, 0.0f, -0.749f, 0.435f, 0.438f, -0.266f, 0.0f, -0.76f, 0.433f, 0.433f,
+ -0.265f, 0.0f, -0.771f, 0.431f, 0.428f, -0.265f, 0.0f, -0.781f, 0.43f, 0.428f, -0.263f, 0.0f, -0.792f, 0.429f, 0.428f, -0.26f, 0.0f, -0.802f, 0.428f, 0.429f,
+ -0.257f, 0.0f, -0.812f, 0.426f, 0.427f, -0.254f, 0.0f, -0.821f, 0.423f, 0.426f, -0.25f, 0.0f, -0.829f, 0.421f, 0.42f, -0.247f, 0.0f, -0.837f, 0.418f, 0.416f,
+ -0.242f, 0.0f, -0.844f, 0.417f, 0.415f, -0.238f, 0.0f, -0.85f, 0.415f, 0.413f, -0.234f, 0.0f, -0.857f, 0.415f, 0.413f, -0.229f, 0.0f, -0.864f, 0.414f, 0.413f,
+ -0.224f, 0.0f, -0.87f, 0.414f, 0.413f, -0.219f, 0.0f, -0.877f, 0.414f, 0.414f, -0.214f, 0.0f, -0.883f, 0.414f, 0.413f, -0.208f, 0.0f, -0.89f, 0.413f, 0.413f,
+ -0.203f, 0.0f, -0.897f, 0.413f, 0.413f, -0.197f, 0.0f, -0.903f, 0.413f, 0.413f, -0.191f, 0.0f, -0.909f, 0.413f, 0.413f, -0.186f, 0.0f, -0.914f, 0.413f, 0.413f,
+ -0.181f, 0.0f, -0.92f, 0.413f, 0.413f, -0.175f, -0.0f, -0.925f, 0.413f, 0.413f, -0.17f, -0.0f, -0.931f, 0.413f, 0.413f, -0.164f, -0.0f, -0.936f, 0.413f, 0.413f,
+ -0.159f, -0.0f, -0.942f, 0.413f, 0.413f, -0.152f, -0.0f, -0.948f, 0.413f, 0.413f, -0.145f, -0.0f, -0.955f, 0.413f, 0.413f, -0.137f, -0.0f, -0.961f, 0.414f, 0.413f,
+ -0.13f, -0.0f, -0.967f, 0.414f, 0.413f, -0.122f, -0.0f, -0.974f, 0.414f, 0.414f, -0.114f, -0.0f, -0.979f, 0.414f, 0.413f, -0.106f, -0.0f, -0.985f, 0.414f, 0.413f,
+ -0.098f, -0.0f, -0.989f, 0.414f, 0.414f, -0.091f, -0.0f, -0.993f, 0.414f, 0.413f, -0.083f, -0.0f, -0.997f, 0.414f, 0.414f, -0.075f, -0.0f, -0.999f, 0.414f, 0.414f,
+ -0.066f, -0.0f, -1.001f, 0.414f, 0.414f, -0.057f, -0.0f, -1.003f, 0.414f, 0.413f, -0.046f, -0.0f, -1.006f, 0.414f, 0.413f, -0.038f, -0.0f, -1.008f, 0.414f, 0.413f,
+ -0.031f, -0.0f, -1.009f, 0.421f, 0.413f, -0.036f, -0.0f, -1.008f, 0.423f, 0.424f, -0.045f, -0.0f, -1.006f, 0.425f, 0.425f, -0.054f, -0.0f, -1.005f, 0.425f, 0.425f,
+ -0.064f, -0.0f, -1.005f, 0.425f, 0.425f, -0.073f, -0.0f, -1.004f, 0.425f, 0.425f, -0.084f, -0.0f, -1.003f, 0.425f, 0.425f, -0.095f, -0.0f, -1.001f, 0.424f, 0.424f,
+ -0.105f, -0.0f, -0.997f, 0.423f, 0.424f, -0.116f, -0.0f, -0.994f, 0.422f, 0.422f, -0.127f, -0.0f, -0.991f, 0.421f, 0.419f, -0.137f, -0.0f, -0.987f, 0.42f, 0.419f,
+ -0.148f, -0.0f, -0.983f, 0.42f, 0.419f, -0.158f, -0.0f, -0.98f, 0.42f, 0.419f, -0.167f, -0.0f, -0.976f, 0.419f, 0.419f, -0.176f, -0.0f, -0.973f, 0.419f, 0.419f,
+ -0.184f, -0.0f, -0.969f, 0.419f, 0.419f, -0.192f, -0.0f, -0.966f, 0.419f, 0.418f, -0.2f, 0.0f, -0.962f, 0.419f, 0.418f, -0.207f, 0.0f, -0.957f, 0.419f, 0.419f,
+ -0.215f, 0.0f, -0.953f, 0.419f, 0.418f, -0.223f, 0.0f, -0.948f, 0.419f, 0.419f, -0.231f, 0.0f, -0.944f, 0.419f, 0.419f, -0.239f, 0.0f, -0.939f, 0.419f, 0.419f,
+ -0.247f, 0.0f, -0.934f, 0.419f, 0.419f, -0.255f, 0.0f, -0.929f, 0.419f, 0.419f, -0.262f, 0.0f, -0.924f, 0.419f, 0.419f, -0.269f, 0.0f, -0.919f, 0.419f, 0.418f,
+ -0.275f, 0.0f, -0.914f, 0.419f, 0.419f, -0.281f, 0.0f, -0.909f, 0.419f, 0.418f, -0.287f, 0.0f, -0.904f, 0.419f, 0.418f, -0.293f, 0.0f, -0.899f, 0.419f, 0.418f,
+ -0.299f, 0.0f, -0.894f, 0.42f, 0.419f, -0.304f, 0.0f, -0.888f, 0.421f, 0.42f, -0.311f, 0.0f, -0.882f, 0.423f, 0.422f, -0.317f, 0.0f, -0.876f, 0.424f, 0.424f,
+ -0.322f, 0.0f, -0.869f, 0.426f, 0.426f, -0.328f, 0.0f, -0.861f, 0.427f, 0.427f, -0.332f, 0.0f, -0.853f, 0.429f, 0.429f, -0.336f, 0.0f, -0.843f, 0.43f, 0.429f,
+ -0.339f, 0.0f, -0.834f, 0.432f, 0.431f, -0.341f, 0.0f, -0.821f, 0.435f, 0.434f, -0.342f, 0.0f, -0.809f, 0.438f, 0.439f, -0.343f, 0.0f, -0.796f, 0.44f, 0.44f,
+ -0.343f, 0.0f, -0.783f, 0.442f, 0.442f, -0.343f, 0.0f, -0.772f, 0.446f, 0.445f, -0.342f, 0.0f, -0.76f, 0.45f, 0.45f, -0.342f, 0.0f, -0.748f, 0.454f, 0.455f,
+ -0.34f, 0.0f, -0.735f, 0.457f, 0.457f, -0.339f, 0.0f, -0.723f, 0.46f, 0.46f, -0.338f, 0.0f, -0.711f, 0.463f, 0.464f, -0.336f, 0.0f, -0.7f, 0.465f, 0.465f,
+ -0.335f, 0.0f, -0.688f, 0.466f, 0.466f, -0.332f, 0.0f, -0.676f, 0.467f, 0.467f, -0.331f, 0.0f, -0.664f, 0.467f, 0.467f, -0.33f, 0.0f, -0.651f, 0.467f, 0.467f,
+ -0.328f, 0.0f, -0.638f, 0.467f, 0.467f, -0.325f, 0.0f, -0.625f, 0.467f, 0.467f, -0.323f, 0.0f, -0.614f, 0.467f, 0.467f, -0.321f, 0.0f, -0.603f, 0.467f, 0.466f,
+ -0.318f, 0.0f, -0.592f, 0.467f, 0.466f, -0.315f, 0.0f, -0.581f, 0.467f, 0.466f, -0.313f, 0.0f, -0.569f, 0.467f, 0.467f, -0.311f, -0.0f, -0.557f, 0.467f, 0.467f,
+ -0.309f, -0.0f, -0.543f, 0.467f, 0.467f, -0.306f, -0.0f, -0.531f, 0.467f, 0.467f, -0.303f, -0.0f, -0.519f, 0.467f, 0.467f, -0.301f, -0.0f, -0.507f, 0.467f, 0.468f,
+ -0.299f, -0.0f, -0.497f, 0.467f, 0.467f, -0.297f, -0.0f, -0.487f, 0.467f, 0.467f, -0.295f, 0.0f, -0.476f, 0.465f, 0.467f, -0.293f, 0.0f, -0.466f, 0.463f, 0.467f,
+ -0.292f, 0.0f, -0.456f, 0.46f, 0.466f, -0.291f, 0.0f, -0.445f, 0.455f, 0.459f, -0.29f, 0.0f, -0.435f, 0.449f, 0.457f, -0.29f, 0.0f, -0.424f, 0.44f, 0.448f,
+ -0.29f, 0.0f, -0.413f, 0.43f, 0.44f, -0.29f, 0.0f, -0.403f, 0.418f, 0.437f, -0.29f, -0.0f, -0.393f, 0.404f, 0.415f, -0.291f, -0.0f, -0.384f, 0.388f, 0.393f,
+ -0.29f, -0.0f, -0.376f, 0.374f, 0.379f, -0.29f, -0.0f, -0.365f, 0.352f, 0.352f,
+};
+
+static const float data8[55 * GP_PRIM_DATABUF_SIZE] = {
+ 0.781f, 0.0f, 0.098f, 0.109f, 0.109f, 0.784f, 0.0f, 0.105f, 0.202f, 0.338f, 0.785f, 0.0f, 0.108f, 0.254f, 0.369f, 0.787f, 0.0f, 0.113f, 0.306f, 0.382f,
+ 0.787f, 0.0f, 0.118f, 0.344f, 0.392f, 0.789f, 0.0f, 0.123f, 0.372f, 0.401f, 0.79f, 0.0f, 0.128f, 0.392f, 0.41f, 0.792f, 0.0f, 0.135f, 0.406f, 0.42f,
+ 0.794f, 0.0f, 0.142f, 0.416f, 0.424f, 0.797f, 0.0f, 0.152f, 0.424f, 0.428f, 0.801f, 0.0f, 0.161f, 0.429f, 0.431f, 0.807f, 0.0f, 0.172f, 0.432f, 0.435f,
+ 0.814f, 0.0f, 0.182f, 0.435f, 0.438f, 0.821f, 0.0f, 0.19f, 0.437f, 0.439f, 0.828f, 0.0f, 0.197f, 0.439f, 0.44f, 0.836f, 0.0f, 0.204f, 0.44f, 0.441f,
+ 0.845f, -0.0f, 0.211f, 0.44f, 0.441f, 0.853f, -0.0f, 0.215f, 0.441f, 0.441f, 0.861f, -0.0f, 0.219f, 0.441f, 0.441f, 0.87f, -0.0f, 0.222f, 0.441f, 0.442f,
+ 0.878f, -0.0f, 0.224f, 0.441f, 0.442f, 0.886f, -0.0f, 0.226f, 0.441f, 0.442f, 0.895f, -0.0f, 0.227f, 0.44f, 0.442f, 0.903f, 0.0f, 0.226f, 0.439f, 0.441f,
+ 0.911f, 0.0f, 0.225f, 0.436f, 0.441f, 0.919f, 0.0f, 0.224f, 0.432f, 0.441f, 0.927f, 0.0f, 0.221f, 0.425f, 0.436f, 0.934f, 0.0f, 0.218f, 0.415f, 0.429f,
+ 0.94f, 0.0f, 0.215f, 0.404f, 0.406f, 0.944f, 0.0f, 0.211f, 0.393f, 0.389f, 0.947f, 0.0f, 0.208f, 0.384f, 0.378f, 0.948f, 0.0f, 0.204f, 0.376f, 0.371f,
+ 0.946f, 0.0f, 0.2f, 0.369f, 0.364f, 0.943f, 0.0f, 0.196f, 0.365f, 0.358f, 0.937f, 0.0f, 0.193f, 0.364f, 0.354f, 0.931f, 0.0f, 0.189f, 0.366f, 0.359f,
+ 0.925f, 0.0f, 0.186f, 0.37f, 0.367f, 0.917f, 0.0f, 0.182f, 0.374f, 0.375f, 0.908f, 0.0f, 0.177f, 0.378f, 0.382f, 0.899f, 0.0f, 0.172f, 0.381f, 0.384f,
+ 0.889f, 0.0f, 0.167f, 0.384f, 0.385f, 0.876f, 0.0f, 0.163f, 0.387f, 0.387f, 0.864f, 0.0f, 0.156f, 0.39f, 0.388f, 0.852f, 0.0f, 0.15f, 0.393f, 0.39f,
+ 0.841f, 0.0f, 0.144f, 0.396f, 0.396f, 0.832f, 0.0f, 0.138f, 0.399f, 0.401f, 0.826f, 0.0f, 0.133f, 0.401f, 0.404f, 0.82f, 0.0f, 0.127f, 0.403f, 0.405f,
+ 0.816f, 0.0f, 0.122f, 0.403f, 0.407f, 0.812f, 0.0f, 0.119f, 0.399f, 0.406f, 0.808f, 0.0f, 0.115f, 0.39f, 0.405f, 0.805f, 0.0f, 0.113f, 0.371f, 0.407f,
+ 0.801f, 0.0f, 0.111f, 0.341f, 0.407f, 0.799f, 0.0f, 0.109f, 0.309f, 0.405f, 0.795f, 0.0f, 0.106f, 0.255f, 0.255f,
+};
+
+static const float data9[70 * GP_PRIM_DATABUF_SIZE] = {
+ 0.819f, -0.0f, 0.325f, 0.109f, 0.109f, 0.829f, -0.0f, 0.328f, 0.258f, 0.403f, 0.835f, -0.0f, 0.329f, 0.327f, 0.428f, 0.843f, -0.0f, 0.331f, 0.383f, 0.452f,
+ 0.851f, -0.0f, 0.332f, 0.419f, 0.465f, 0.861f, -0.0f, 0.334f, 0.444f, 0.473f, 0.87f, -0.0f, 0.336f, 0.461f, 0.48f, 0.881f, -0.0f, 0.337f, 0.473f, 0.486f,
+ 0.892f, -0.0f, 0.339f, 0.482f, 0.496f, 0.904f, -0.0f, 0.341f, 0.489f, 0.501f, 0.917f, -0.0f, 0.342f, 0.494f, 0.503f, 0.931f, -0.0f, 0.342f, 0.498f, 0.505f,
+ 0.945f, -0.0f, 0.342f, 0.501f, 0.505f, 0.958f, -0.0f, 0.342f, 0.503f, 0.506f, 0.971f, -0.0f, 0.341f, 0.505f, 0.506f, 0.984f, -0.0f, 0.341f, 0.506f, 0.506f,
+ 0.997f, -0.0f, 0.339f, 0.507f, 0.508f, 1.009f, -0.0f, 0.337f, 0.507f, 0.507f, 1.021f, -0.0f, 0.333f, 0.508f, 0.508f, 1.033f, -0.0f, 0.33f, 0.508f, 0.508f,
+ 1.044f, -0.0f, 0.326f, 0.508f, 0.508f, 1.056f, -0.0f, 0.322f, 0.508f, 0.508f, 1.068f, -0.0f, 0.317f, 0.508f, 0.508f, 1.078f, -0.0f, 0.311f, 0.507f, 0.508f,
+ 1.089f, -0.0f, 0.304f, 0.506f, 0.508f, 1.099f, 0.0f, 0.294f, 0.503f, 0.506f, 1.107f, 0.0f, 0.287f, 0.498f, 0.506f, 1.113f, 0.0f, 0.28f, 0.49f, 0.505f,
+ 1.117f, 0.0f, 0.276f, 0.48f, 0.501f, 1.121f, 0.0f, 0.272f, 0.468f, 0.492f, 1.124f, 0.0f, 0.27f, 0.455f, 0.467f, 1.127f, 0.0f, 0.27f, 0.443f, 0.431f,
+ 1.129f, 0.0f, 0.271f, 0.431f, 0.4f, 1.13f, 0.0f, 0.274f, 0.422f, 0.399f, 1.13f, 0.0f, 0.278f, 0.414f, 0.399f, 1.13f, 0.0f, 0.286f, 0.408f, 0.399f,
+ 1.128f, 0.0f, 0.295f, 0.404f, 0.399f, 1.124f, 0.0f, 0.305f, 0.402f, 0.399f, 1.119f, 0.0f, 0.316f, 0.403f, 0.4f, 1.113f, -0.0f, 0.327f, 0.405f, 0.401f,
+ 1.107f, -0.0f, 0.337f, 0.408f, 0.411f, 1.1f, -0.0f, 0.345f, 0.412f, 0.412f, 1.094f, -0.0f, 0.352f, 0.416f, 0.413f, 1.087f, -0.0f, 0.357f, 0.421f, 0.422f,
+ 1.08f, -0.0f, 0.363f, 0.426f, 0.428f, 1.071f, -0.0f, 0.368f, 0.429f, 0.43f, 1.062f, -0.0f, 0.373f, 0.431f, 0.431f, 1.051f, -0.0f, 0.377f, 0.433f, 0.431f,
+ 1.039f, -0.0f, 0.381f, 0.436f, 0.437f, 1.026f, -0.0f, 0.383f, 0.438f, 0.44f, 1.013f, -0.0f, 0.384f, 0.44f, 0.44f, 1.0f, -0.0f, 0.385f, 0.441f, 0.443f,
+ 0.987f, -0.0f, 0.385f, 0.442f, 0.443f, 0.975f, -0.0f, 0.384f, 0.443f, 0.443f, 0.962f, -0.0f, 0.383f, 0.443f, 0.444f, 0.949f, -0.0f, 0.381f, 0.443f, 0.443f,
+ 0.936f, -0.0f, 0.38f, 0.443f, 0.444f, 0.923f, -0.0f, 0.378f, 0.443f, 0.444f, 0.909f, -0.0f, 0.375f, 0.443f, 0.444f, 0.897f, -0.0f, 0.371f, 0.443f, 0.444f,
+ 0.886f, -0.0f, 0.367f, 0.443f, 0.443f, 0.876f, -0.0f, 0.363f, 0.443f, 0.444f, 0.868f, -0.0f, 0.359f, 0.443f, 0.442f, 0.86f, -0.0f, 0.355f, 0.442f, 0.443f,
+ 0.852f, -0.0f, 0.35f, 0.441f, 0.443f, 0.844f, -0.0f, 0.347f, 0.433f, 0.443f, 0.837f, -0.0f, 0.343f, 0.409f, 0.443f, 0.83f, -0.0f, 0.338f, 0.344f, 0.443f,
+ 0.824f, -0.0f, 0.335f, 0.239f, 0.437f, 0.815f, -0.0f, 0.326f, 0.0f, 0.003f,
+};
+
+static const float data10[227 * GP_PRIM_DATABUF_SIZE] = {
+ -0.675f, 0.0f, 0.411f, 0.099f, 0.099f, -0.669f, 0.0f, 0.418f, 0.358f, 0.358f, -0.666f, 0.0f, 0.424f, 0.381f, 0.381f, -0.662f, 0.0f, 0.431f, 0.389f, 0.389f,
+ -0.658f, 0.0f, 0.438f, 0.393f, 0.393f, -0.649f, 0.0f, 0.448f, 0.404f, 0.404f, -0.641f, 0.0f, 0.458f, 0.419f, 0.419f, -0.632f, 0.0f, 0.468f, 0.431f, 0.434f,
+ -0.626f, 0.0f, 0.476f, 0.435f, 0.436f, -0.62f, 0.0f, 0.484f, 0.437f, 0.438f, -0.615f, 0.0f, 0.492f, 0.439f, 0.439f, -0.61f, 0.0f, 0.499f, 0.439f, 0.44f,
+ -0.605f, 0.0f, 0.506f, 0.44f, 0.44f, -0.6f, 0.0f, 0.512f, 0.44f, 0.44f, -0.595f, 0.0f, 0.519f, 0.44f, 0.44f, -0.59f, 0.0f, 0.526f, 0.441f, 0.441f,
+ -0.584f, 0.0f, 0.532f, 0.441f, 0.441f, -0.579f, 0.0f, 0.539f, 0.441f, 0.441f, -0.573f, 0.0f, 0.545f, 0.442f, 0.442f, -0.566f, 0.0f, 0.551f, 0.443f, 0.443f,
+ -0.559f, 0.0f, 0.557f, 0.443f, 0.443f, -0.552f, 0.0f, 0.563f, 0.444f, 0.444f, -0.545f, 0.0f, 0.569f, 0.445f, 0.445f, -0.538f, 0.0f, 0.576f, 0.447f, 0.447f,
+ -0.532f, 0.0f, 0.582f, 0.448f, 0.448f, -0.525f, 0.0f, 0.589f, 0.45f, 0.45f, -0.519f, 0.0f, 0.595f, 0.451f, 0.452f, -0.513f, 0.0f, 0.602f, 0.452f, 0.453f,
+ -0.506f, 0.0f, 0.608f, 0.453f, 0.453f, -0.5f, 0.0f, 0.613f, 0.453f, 0.454f, -0.493f, 0.0f, 0.619f, 0.453f, 0.454f, -0.486f, 0.0f, 0.625f, 0.453f, 0.454f,
+ -0.479f, 0.0f, 0.631f, 0.453f, 0.454f, -0.472f, 0.0f, 0.637f, 0.453f, 0.454f, -0.464f, 0.0f, 0.642f, 0.453f, 0.454f, -0.457f, 0.0f, 0.649f, 0.453f, 0.454f,
+ -0.45f, 0.0f, 0.655f, 0.453f, 0.453f, -0.443f, 0.0f, 0.661f, 0.453f, 0.453f, -0.435f, 0.0f, 0.667f, 0.453f, 0.454f, -0.427f, 0.0f, 0.672f, 0.453f, 0.454f,
+ -0.419f, 0.0f, 0.677f, 0.453f, 0.454f, -0.411f, 0.0f, 0.682f, 0.453f, 0.453f, -0.403f, 0.0f, 0.688f, 0.453f, 0.453f, -0.395f, 0.0f, 0.692f, 0.453f, 0.454f,
+ -0.387f, 0.0f, 0.697f, 0.453f, 0.454f, -0.379f, 0.0f, 0.702f, 0.453f, 0.454f, -0.372f, 0.0f, 0.707f, 0.454f, 0.454f, -0.364f, 0.0f, 0.712f, 0.454f, 0.454f,
+ -0.356f, 0.0f, 0.716f, 0.454f, 0.454f, -0.349f, 0.0f, 0.721f, 0.454f, 0.454f, -0.342f, 0.0f, 0.725f, 0.454f, 0.454f, -0.334f, 0.0f, 0.73f, 0.454f, 0.454f,
+ -0.326f, 0.0f, 0.733f, 0.454f, 0.454f, -0.318f, 0.0f, 0.737f, 0.454f, 0.454f, -0.31f, 0.0f, 0.74f, 0.454f, 0.454f, -0.301f, 0.0f, 0.743f, 0.454f, 0.454f,
+ -0.293f, 0.0f, 0.746f, 0.454f, 0.455f, -0.284f, 0.0f, 0.749f, 0.454f, 0.455f, -0.274f, 0.0f, 0.752f, 0.455f, 0.455f, -0.265f, 0.0f, 0.755f, 0.455f, 0.455f,
+ -0.255f, 0.0f, 0.757f, 0.455f, 0.455f, -0.245f, 0.0f, 0.76f, 0.456f, 0.455f, -0.234f, 0.0f, 0.762f, 0.457f, 0.456f, -0.223f, 0.0f, 0.764f, 0.458f, 0.458f,
+ -0.212f, 0.0f, 0.766f, 0.459f, 0.46f, -0.201f, 0.0f, 0.769f, 0.461f, 0.46f, -0.189f, 0.0f, 0.771f, 0.462f, 0.461f, -0.177f, 0.0f, 0.773f, 0.464f, 0.463f,
+ -0.166f, 0.0f, 0.775f, 0.465f, 0.465f, -0.153f, 0.0f, 0.777f, 0.467f, 0.467f, -0.141f, 0.0f, 0.779f, 0.469f, 0.469f, -0.128f, 0.0f, 0.781f, 0.472f, 0.472f,
+ -0.116f, 0.0f, 0.782f, 0.474f, 0.473f, -0.101f, 0.0f, 0.782f, 0.477f, 0.477f, -0.087f, 0.0f, 0.783f, 0.482f, 0.477f, -0.073f, 0.0f, 0.783f, 0.489f, 0.483f,
+ -0.059f, 0.0f, 0.783f, 0.497f, 0.5f, -0.046f, 0.0f, 0.784f, 0.503f, 0.509f, -0.033f, 0.0f, 0.784f, 0.508f, 0.51f, -0.022f, 0.0f, 0.784f, 0.51f, 0.512f,
+ -0.011f, 0.0f, 0.785f, 0.512f, 0.512f, -0.0f, 0.0f, 0.786f, 0.513f, 0.512f, 0.011f, 0.0f, 0.786f, 0.515f, 0.513f, 0.022f, 0.0f, 0.786f, 0.517f, 0.517f,
+ 0.032f, 0.0f, 0.786f, 0.52f, 0.519f, 0.044f, 0.0f, 0.786f, 0.522f, 0.524f, 0.055f, 0.0f, 0.785f, 0.525f, 0.525f, 0.066f, 0.0f, 0.785f, 0.527f, 0.525f,
+ 0.076f, 0.0f, 0.784f, 0.53f, 0.53f, 0.086f, 0.0f, 0.783f, 0.532f, 0.533f, 0.097f, 0.0f, 0.782f, 0.535f, 0.534f, 0.108f, 0.0f, 0.782f, 0.538f, 0.541f,
+ 0.119f, 0.0f, 0.781f, 0.54f, 0.542f, 0.13f, 0.0f, 0.781f, 0.543f, 0.543f, 0.141f, 0.0f, 0.78f, 0.545f, 0.545f, 0.154f, 0.0f, 0.779f, 0.547f, 0.547f,
+ 0.165f, 0.0f, 0.777f, 0.549f, 0.548f, 0.177f, 0.0f, 0.775f, 0.55f, 0.552f, 0.188f, 0.0f, 0.772f, 0.552f, 0.552f, 0.199f, 0.0f, 0.77f, 0.553f, 0.553f,
+ 0.209f, 0.0f, 0.767f, 0.554f, 0.554f, 0.218f, 0.0f, 0.765f, 0.555f, 0.556f, 0.226f, 0.0f, 0.763f, 0.556f, 0.557f, 0.235f, 0.0f, 0.761f, 0.557f, 0.557f,
+ 0.244f, 0.0f, 0.758f, 0.558f, 0.558f, 0.253f, 0.0f, 0.755f, 0.559f, 0.559f, 0.263f, 0.0f, 0.752f, 0.56f, 0.559f, 0.272f, 0.0f, 0.749f, 0.561f, 0.56f,
+ 0.285f, 0.0f, 0.745f, 0.562f, 0.56f, 0.299f, 0.0f, 0.741f, 0.563f, 0.563f, 0.316f, 0.0f, 0.736f, 0.564f, 0.564f, 0.331f, 0.0f, 0.728f, 0.565f, 0.567f,
+ 0.349f, 0.0f, 0.718f, 0.565f, 0.568f, 0.365f, 0.0f, 0.708f, 0.566f, 0.568f, 0.38f, 0.0f, 0.699f, 0.566f, 0.568f, 0.39f, 0.0f, 0.693f, 0.566f, 0.568f,
+ 0.397f, 0.0f, 0.687f, 0.566f, 0.569f, 0.4f, 0.0f, 0.683f, 0.566f, 0.569f, 0.401f, 0.0f, 0.681f, 0.565f, 0.57f, 0.4f, 0.0f, 0.679f, 0.565f, 0.57f,
+ 0.397f, 0.0f, 0.678f, 0.564f, 0.57f, 0.393f, 0.0f, 0.678f, 0.564f, 0.565f, 0.387f, 0.0f, 0.678f, 0.563f, 0.559f, 0.379f, 0.0f, 0.679f, 0.562f, 0.558f,
+ 0.37f, 0.0f, 0.681f, 0.561f, 0.557f, 0.357f, 0.0f, 0.684f, 0.561f, 0.557f, 0.342f, 0.0f, 0.689f, 0.56f, 0.557f, 0.324f, 0.0f, 0.694f, 0.56f, 0.557f,
+ 0.307f, 0.0f, 0.697f, 0.559f, 0.558f, 0.291f, 0.0f, 0.699f, 0.559f, 0.558f, 0.274f, 0.0f, 0.701f, 0.559f, 0.557f, 0.26f, 0.0f, 0.703f, 0.558f, 0.558f,
+ 0.246f, 0.0f, 0.705f, 0.558f, 0.558f, 0.235f, 0.0f, 0.707f, 0.558f, 0.558f, 0.224f, 0.0f, 0.709f, 0.558f, 0.558f, 0.214f, 0.0f, 0.711f, 0.558f, 0.558f,
+ 0.203f, 0.0f, 0.713f, 0.558f, 0.559f, 0.192f, 0.0f, 0.714f, 0.558f, 0.558f, 0.181f, 0.0f, 0.714f, 0.557f, 0.557f, 0.17f, 0.0f, 0.714f, 0.557f, 0.557f,
+ 0.16f, 0.0f, 0.715f, 0.557f, 0.556f, 0.149f, 0.0f, 0.715f, 0.557f, 0.556f, 0.139f, 0.0f, 0.716f, 0.557f, 0.556f, 0.129f, 0.0f, 0.716f, 0.558f, 0.556f,
+ 0.119f, 0.0f, 0.717f, 0.558f, 0.556f, 0.109f, 0.0f, 0.717f, 0.558f, 0.557f, 0.099f, 0.0f, 0.718f, 0.558f, 0.557f, 0.089f, 0.0f, 0.718f, 0.559f, 0.557f,
+ 0.079f, 0.0f, 0.718f, 0.559f, 0.558f, 0.068f, 0.0f, 0.719f, 0.559f, 0.559f, 0.057f, 0.0f, 0.719f, 0.56f, 0.56f, 0.046f, 0.0f, 0.718f, 0.56f, 0.561f,
+ 0.035f, 0.0f, 0.718f, 0.561f, 0.561f, 0.024f, 0.0f, 0.718f, 0.561f, 0.562f, 0.013f, 0.0f, 0.717f, 0.562f, 0.562f, 0.002f, 0.0f, 0.717f, 0.562f, 0.563f,
+ -0.01f, 0.0f, 0.717f, 0.563f, 0.564f, -0.021f, 0.0f, 0.717f, 0.563f, 0.564f, -0.032f, 0.0f, 0.716f, 0.563f, 0.564f, -0.044f, 0.0f, 0.715f, 0.564f, 0.564f,
+ -0.055f, 0.0f, 0.714f, 0.564f, 0.565f, -0.066f, 0.0f, 0.713f, 0.564f, 0.565f, -0.078f, 0.0f, 0.712f, 0.564f, 0.564f, -0.089f, 0.0f, 0.711f, 0.564f, 0.564f,
+ -0.101f, 0.0f, 0.709f, 0.565f, 0.564f, -0.112f, 0.0f, 0.708f, 0.565f, 0.564f, -0.124f, 0.0f, 0.707f, 0.565f, 0.564f, -0.135f, 0.0f, 0.705f, 0.565f, 0.564f,
+ -0.146f, 0.0f, 0.704f, 0.566f, 0.564f, -0.158f, 0.0f, 0.702f, 0.566f, 0.564f, -0.169f, 0.0f, 0.7f, 0.566f, 0.566f, -0.18f, 0.0f, 0.698f, 0.567f, 0.568f,
+ -0.191f, 0.0f, 0.696f, 0.567f, 0.568f, -0.203f, 0.0f, 0.693f, 0.567f, 0.568f, -0.215f, 0.0f, 0.69f, 0.567f, 0.568f, -0.227f, 0.0f, 0.687f, 0.567f, 0.568f,
+ -0.238f, 0.0f, 0.684f, 0.567f, 0.568f, -0.25f, 0.0f, 0.681f, 0.567f, 0.569f, -0.262f, 0.0f, 0.678f, 0.567f, 0.569f, -0.273f, 0.0f, 0.675f, 0.567f, 0.567f,
+ -0.284f, 0.0f, 0.673f, 0.567f, 0.566f, -0.295f, 0.0f, 0.671f, 0.567f, 0.567f, -0.305f, 0.0f, 0.669f, 0.566f, 0.567f, -0.316f, 0.0f, 0.666f, 0.566f, 0.567f,
+ -0.326f, 0.0f, 0.663f, 0.565f, 0.566f, -0.337f, 0.0f, 0.66f, 0.565f, 0.566f, -0.348f, 0.0f, 0.655f, 0.564f, 0.564f, -0.359f, 0.0f, 0.652f, 0.563f, 0.564f,
+ -0.369f, 0.0f, 0.648f, 0.562f, 0.563f, -0.379f, 0.0f, 0.644f, 0.561f, 0.56f, -0.389f, 0.0f, 0.64f, 0.561f, 0.559f, -0.399f, 0.0f, 0.636f, 0.56f, 0.559f,
+ -0.409f, 0.0f, 0.633f, 0.559f, 0.559f, -0.419f, 0.0f, 0.629f, 0.559f, 0.559f, -0.428f, 0.0f, 0.625f, 0.559f, 0.558f, -0.438f, 0.0f, 0.62f, 0.559f, 0.559f,
+ -0.447f, 0.0f, 0.615f, 0.559f, 0.559f, -0.457f, 0.0f, 0.61f, 0.559f, 0.559f, -0.466f, 0.0f, 0.605f, 0.559f, 0.559f, -0.474f, 0.0f, 0.6f, 0.559f, 0.559f,
+ -0.483f, 0.0f, 0.595f, 0.559f, 0.559f, -0.492f, 0.0f, 0.591f, 0.559f, 0.559f, -0.5f, 0.0f, 0.586f, 0.559f, 0.559f, -0.508f, 0.0f, 0.58f, 0.559f, 0.559f,
+ -0.515f, 0.0f, 0.574f, 0.559f, 0.559f, -0.523f, 0.0f, 0.568f, 0.559f, 0.559f, -0.531f, 0.0f, 0.562f, 0.559f, 0.558f, -0.54f, 0.0f, 0.556f, 0.559f, 0.558f,
+ -0.548f, 0.0f, 0.549f, 0.559f, 0.559f, -0.556f, 0.0f, 0.543f, 0.559f, 0.559f, -0.562f, 0.0f, 0.537f, 0.559f, 0.559f, -0.568f, 0.0f, 0.531f, 0.559f, 0.559f,
+ -0.574f, 0.0f, 0.524f, 0.559f, 0.559f, -0.58f, 0.0f, 0.518f, 0.558f, 0.559f, -0.586f, 0.0f, 0.512f, 0.557f, 0.558f, -0.591f, 0.0f, 0.506f, 0.555f, 0.557f,
+ -0.597f, 0.0f, 0.5f, 0.551f, 0.556f, -0.603f, 0.0f, 0.493f, 0.546f, 0.547f, -0.609f, 0.0f, 0.487f, 0.541f, 0.538f, -0.614f, 0.0f, 0.48f, 0.536f, 0.535f,
+ -0.621f, 0.0f, 0.473f, 0.534f, 0.534f, -0.628f, 0.0f, 0.467f, 0.534f, 0.534f, -0.637f, 0.0f, 0.459f, 0.534f, 0.534f, -0.642f, 0.0f, 0.452f, 0.532f, 0.532f,
+ -0.65f, 0.0f, 0.445f, 0.528f, 0.528f, -0.654f, 0.0f, 0.438f, 0.525f, 0.525f, -0.659f, 0.0f, 0.431f, 0.522f, 0.522f,
+};
+
+static const float data11[1 * GP_PRIM_DATABUF_SIZE] = {
+ -0.525f, 0.0f, 0.174f, 0.124f, 0.124f,
+};
+
+static const float data12[123 * GP_PRIM_DATABUF_SIZE] = {
+ -0.53f, 0.0f, 0.193f, 0.147f, 0.147f, -0.532f, 0.0f, 0.186f, 0.316f, 0.316f, -0.534f, 0.0f, 0.18f, 0.353f, 0.353f, -0.535f, 0.0f, 0.173f, 0.382f, 0.382f,
+ -0.537f, 0.0f, 0.165f, 0.384f, 0.384f, -0.538f, 0.0f, 0.155f, 0.387f, 0.387f, -0.539f, 0.0f, 0.145f, 0.393f, 0.393f, -0.54f, -0.0f, 0.134f, 0.399f, 0.399f,
+ -0.541f, -0.0f, 0.123f, 0.4f, 0.4f, -0.542f, -0.0f, 0.11f, 0.401f, 0.401f, -0.542f, 0.0f, 0.094f, 0.402f, 0.402f, -0.54f, 0.0f, 0.078f, 0.403f, 0.403f,
+ -0.538f, 0.0f, 0.061f, 0.404f, 0.404f, -0.535f, 0.0f, 0.045f, 0.404f, 0.404f, -0.531f, 0.0f, 0.031f, 0.404f, 0.404f, -0.526f, 0.0f, 0.018f, 0.404f, 0.404f,
+ -0.52f, -0.0f, 0.005f, 0.405f, 0.405f, -0.513f, -0.0f, -0.01f, 0.405f, 0.405f, -0.505f, -0.0f, -0.024f, 0.405f, 0.405f, -0.495f, -0.0f, -0.037f, 0.405f, 0.405f,
+ -0.485f, 0.0f, -0.051f, 0.405f, 0.405f, -0.474f, 0.0f, -0.064f, 0.406f, 0.406f, -0.462f, 0.0f, -0.076f, 0.405f, 0.405f, -0.451f, 0.0f, -0.086f, 0.406f, 0.406f,
+ -0.442f, 0.0f, -0.094f, 0.406f, 0.406f, -0.432f, 0.0f, -0.102f, 0.406f, 0.406f, -0.422f, 0.0f, -0.108f, 0.405f, 0.405f, -0.411f, 0.0f, -0.114f, 0.406f, 0.406f,
+ -0.4f, 0.0f, -0.119f, 0.405f, 0.405f, -0.389f, 0.0f, -0.122f, 0.406f, 0.406f, -0.378f, 0.0f, -0.125f, 0.407f, 0.407f, -0.365f, 0.0f, -0.127f, 0.412f, 0.412f,
+ -0.354f, 0.0f, -0.129f, 0.418f, 0.418f, -0.342f, 0.0f, -0.131f, 0.44f, 0.44f, -0.33f, 0.0f, -0.131f, 0.448f, 0.448f, -0.317f, 0.0f, -0.131f, 0.469f, 0.469f,
+ -0.305f, 0.0f, -0.13f, 0.477f, 0.477f, -0.293f, 0.0f, -0.128f, 0.482f, 0.482f, -0.278f, 0.0f, -0.125f, 0.494f, 0.494f, -0.266f, 0.0f, -0.121f, 0.5f, 0.5f,
+ -0.253f, 0.0f, -0.116f, 0.507f, 0.507f, -0.242f, 0.0f, -0.111f, 0.509f, 0.509f, -0.231f, 0.0f, -0.105f, 0.511f, 0.511f, -0.222f, 0.0f, -0.099f, 0.511f, 0.511f,
+ -0.213f, 0.0f, -0.092f, 0.512f, 0.512f, -0.206f, 0.0f, -0.084f, 0.513f, 0.513f, -0.199f, 0.0f, -0.076f, 0.514f, 0.514f, -0.192f, 0.0f, -0.067f, 0.515f, 0.515f,
+ -0.186f, -0.0f, -0.058f, 0.516f, 0.516f, -0.18f, -0.0f, -0.049f, 0.516f, 0.516f, -0.175f, -0.0f, -0.04f, 0.515f, 0.515f, -0.17f, -0.0f, -0.03f, 0.515f, 0.515f,
+ -0.166f, -0.0f, -0.02f, 0.516f, 0.516f, -0.163f, -0.0f, -0.01f, 0.504f, 0.504f, -0.159f, -0.0f, 0.002f, 0.502f, 0.502f, -0.155f, -0.0f, 0.014f, 0.501f, 0.501f,
+ -0.152f, -0.0f, 0.027f, 0.502f, 0.502f, -0.149f, -0.0f, 0.043f, 0.5f, 0.5f, -0.148f, -0.0f, 0.058f, 0.49f, 0.49f, -0.147f, -0.0f, 0.075f, 0.47f, 0.47f,
+ -0.146f, -0.0f, 0.09f, 0.463f, 0.463f, -0.146f, -0.0f, 0.105f, 0.454f, 0.454f, -0.146f, -0.0f, 0.12f, 0.427f, 0.427f, -0.148f, 0.0f, 0.133f, 0.413f, 0.413f,
+ -0.15f, 0.0f, 0.144f, 0.4f, 0.4f, -0.153f, 0.0f, 0.152f, 0.383f, 0.383f, -0.156f, 0.0f, 0.157f, 0.369f, 0.369f, -0.158f, 0.0f, 0.16f, 0.36f, 0.36f,
+ -0.16f, 0.0f, 0.158f, 0.349f, 0.349f, -0.162f, 0.0f, 0.154f, 0.364f, 0.364f, -0.164f, 0.0f, 0.147f, 0.37f, 0.37f, -0.166f, 0.0f, 0.139f, 0.378f, 0.378f,
+ -0.168f, 0.0f, 0.13f, 0.386f, 0.386f, -0.172f, 0.0f, 0.119f, 0.394f, 0.394f, -0.176f, -0.0f, 0.108f, 0.405f, 0.405f, -0.18f, -0.0f, 0.096f, 0.412f, 0.412f,
+ -0.185f, -0.0f, 0.084f, 0.417f, 0.417f, -0.191f, -0.0f, 0.073f, 0.425f, 0.425f, -0.196f, -0.0f, 0.063f, 0.431f, 0.431f, -0.202f, -0.0f, 0.053f, 0.441f, 0.441f,
+ -0.208f, -0.0f, 0.043f, 0.444f, 0.444f, -0.214f, -0.0f, 0.034f, 0.451f, 0.451f, -0.22f, 0.0f, 0.026f, 0.46f, 0.46f, -0.226f, 0.0f, 0.018f, 0.463f, 0.463f,
+ -0.232f, 0.0f, 0.01f, 0.474f, 0.474f, -0.239f, 0.0f, 0.004f, 0.477f, 0.477f, -0.247f, 0.0f, -0.003f, 0.48f, 0.48f, -0.255f, 0.0f, -0.008f, 0.483f, 0.483f,
+ -0.264f, 0.0f, -0.013f, 0.497f, 0.497f, -0.274f, 0.0f, -0.018f, 0.501f, 0.501f, -0.285f, 0.0f, -0.022f, 0.505f, 0.505f, -0.297f, 0.0f, -0.024f, 0.509f, 0.509f,
+ -0.311f, 0.0f, -0.025f, 0.51f, 0.51f, -0.325f, 0.0f, -0.024f, 0.512f, 0.512f, -0.339f, 0.0f, -0.023f, 0.512f, 0.512f, -0.354f, 0.0f, -0.022f, 0.513f, 0.513f,
+ -0.368f, 0.0f, -0.02f, 0.513f, 0.513f, -0.382f, 0.0f, -0.017f, 0.514f, 0.514f, -0.397f, 0.0f, -0.013f, 0.514f, 0.514f, -0.41f, 0.0f, -0.007f, 0.514f, 0.514f,
+ -0.422f, 0.0f, 0.001f, 0.513f, 0.513f, -0.434f, 0.0f, 0.009f, 0.514f, 0.514f, -0.446f, 0.0f, 0.018f, 0.514f, 0.514f, -0.458f, 0.0f, 0.028f, 0.514f, 0.514f,
+ -0.47f, -0.0f, 0.039f, 0.514f, 0.514f, -0.48f, 0.0f, 0.048f, 0.514f, 0.514f, -0.487f, 0.0f, 0.057f, 0.514f, 0.514f, -0.493f, 0.0f, 0.068f, 0.514f, 0.514f,
+ -0.498f, 0.0f, 0.08f, 0.514f, 0.514f, -0.502f, 0.0f, 0.092f, 0.514f, 0.514f, -0.506f, 0.0f, 0.104f, 0.514f, 0.514f, -0.509f, -0.0f, 0.116f, 0.515f, 0.515f,
+ -0.511f, -0.0f, 0.125f, 0.515f, 0.515f, -0.513f, -0.0f, 0.133f, 0.515f, 0.515f, -0.515f, -0.0f, 0.141f, 0.515f, 0.515f, -0.517f, 0.0f, 0.148f, 0.515f, 0.515f,
+ -0.519f, 0.0f, 0.155f, 0.514f, 0.514f, -0.52f, 0.0f, 0.161f, 0.514f, 0.514f, -0.522f, 0.0f, 0.168f, 0.514f, 0.514f, -0.523f, 0.0f, 0.174f, 0.514f, 0.514f,
+ -0.525f, 0.0f, 0.18f, 0.514f, 0.514f, -0.526f, 0.0f, 0.185f, 0.514f, 0.514f, -0.527f, 0.0f, 0.191f, 0.513f, 0.513f,
+};
+
+static const float data13[125 * GP_PRIM_DATABUF_SIZE] = {
+ 0.184f, 0.0f, 0.22f, 0.026f, 0.026f, 0.182f, 0.0f, 0.21f, 0.275f, 0.275f, 0.18f, 0.0f, 0.203f, 0.301f, 0.301f, 0.178f, 0.0f, 0.195f, 0.322f, 0.322f,
+ 0.176f, 0.0f, 0.186f, 0.343f, 0.343f, 0.173f, 0.0f, 0.176f, 0.36f, 0.36f, 0.17f, -0.0f, 0.166f, 0.367f, 0.367f, 0.168f, -0.0f, 0.156f, 0.38f, 0.38f,
+ 0.165f, -0.0f, 0.145f, 0.385f, 0.385f, 0.163f, -0.0f, 0.132f, 0.391f, 0.391f, 0.161f, -0.0f, 0.119f, 0.401f, 0.401f, 0.16f, -0.0f, 0.103f, 0.405f, 0.405f,
+ 0.161f, -0.0f, 0.086f, 0.405f, 0.405f, 0.163f, -0.0f, 0.068f, 0.407f, 0.407f, 0.165f, 0.0f, 0.051f, 0.409f, 0.409f, 0.168f, 0.0f, 0.034f, 0.409f, 0.409f,
+ 0.172f, 0.0f, 0.018f, 0.409f, 0.409f, 0.177f, 0.0f, 0.004f, 0.409f, 0.409f, 0.183f, 0.0f, -0.008f, 0.411f, 0.411f, 0.19f, 0.0f, -0.022f, 0.411f, 0.411f,
+ 0.196f, 0.0f, -0.034f, 0.411f, 0.411f, 0.203f, 0.0f, -0.045f, 0.411f, 0.411f, 0.211f, 0.0f, -0.055f, 0.411f, 0.411f, 0.219f, 0.0f, -0.064f, 0.411f, 0.411f,
+ 0.227f, 0.0f, -0.072f, 0.411f, 0.411f, 0.235f, 0.0f, -0.08f, 0.412f, 0.412f, 0.244f, 0.0f, -0.087f, 0.412f, 0.412f, 0.253f, 0.0f, -0.094f, 0.413f, 0.413f,
+ 0.262f, 0.0f, -0.1f, 0.413f, 0.413f, 0.273f, 0.0f, -0.105f, 0.413f, 0.413f, 0.284f, 0.0f, -0.11f, 0.413f, 0.413f, 0.295f, 0.0f, -0.114f, 0.419f, 0.419f,
+ 0.307f, 0.0f, -0.117f, 0.425f, 0.425f, 0.321f, -0.0f, -0.118f, 0.433f, 0.433f, 0.334f, -0.0f, -0.12f, 0.446f, 0.446f, 0.347f, -0.0f, -0.12f, 0.474f, 0.474f,
+ 0.36f, -0.0f, -0.12f, 0.481f, 0.481f, 0.374f, -0.0f, -0.119f, 0.491f, 0.491f, 0.387f, -0.0f, -0.118f, 0.494f, 0.494f, 0.401f, 0.0f, -0.116f, 0.5f, 0.5f,
+ 0.414f, 0.0f, -0.112f, 0.505f, 0.505f, 0.426f, -0.0f, -0.107f, 0.51f, 0.51f, 0.438f, -0.0f, -0.101f, 0.513f, 0.513f, 0.449f, -0.0f, -0.094f, 0.515f, 0.515f,
+ 0.46f, -0.0f, -0.086f, 0.517f, 0.517f, 0.47f, -0.0f, -0.078f, 0.519f, 0.519f, 0.478f, -0.0f, -0.07f, 0.52f, 0.52f, 0.486f, -0.0f, -0.061f, 0.522f, 0.522f,
+ 0.493f, -0.0f, -0.052f, 0.523f, 0.523f, 0.499f, -0.0f, -0.044f, 0.522f, 0.522f, 0.505f, -0.0f, -0.035f, 0.522f, 0.522f, 0.51f, -0.0f, -0.027f, 0.523f, 0.523f,
+ 0.514f, -0.0f, -0.018f, 0.523f, 0.523f, 0.517f, -0.0f, -0.009f, 0.523f, 0.523f, 0.52f, -0.0f, -0.001f, 0.524f, 0.524f, 0.522f, -0.0f, 0.008f, 0.523f, 0.523f,
+ 0.525f, -0.0f, 0.018f, 0.521f, 0.522f, 0.527f, -0.0f, 0.027f, 0.515f, 0.514f, 0.529f, -0.0f, 0.036f, 0.512f, 0.512f, 0.531f, -0.0f, 0.045f, 0.509f, 0.51f,
+ 0.533f, -0.0f, 0.053f, 0.506f, 0.505f, 0.535f, -0.0f, 0.062f, 0.503f, 0.503f, 0.536f, -0.0f, 0.071f, 0.5f, 0.5f, 0.538f, -0.0f, 0.08f, 0.496f, 0.497f,
+ 0.538f, -0.0f, 0.09f, 0.491f, 0.492f, 0.539f, -0.0f, 0.1f, 0.485f, 0.486f, 0.539f, 0.0f, 0.11f, 0.475f, 0.476f, 0.539f, 0.0f, 0.12f, 0.46f, 0.459f,
+ 0.539f, 0.0f, 0.13f, 0.444f, 0.448f, 0.538f, 0.0f, 0.139f, 0.406f, 0.405f, 0.537f, 0.0f, 0.144f, 0.399f, 0.399f, 0.536f, 0.0f, 0.146f, 0.395f, 0.395f,
+ 0.535f, 0.0f, 0.144f, 0.412f, 0.412f, 0.533f, 0.0f, 0.139f, 0.413f, 0.413f, 0.53f, 0.0f, 0.131f, 0.414f, 0.413f, 0.528f, 0.0f, 0.122f, 0.419f, 0.418f,
+ 0.525f, 0.0f, 0.112f, 0.425f, 0.424f, 0.521f, 0.0f, 0.102f, 0.444f, 0.444f, 0.518f, 0.0f, 0.094f, 0.451f, 0.452f, 0.514f, 0.0f, 0.085f, 0.457f, 0.457f,
+ 0.509f, 0.0f, 0.078f, 0.461f, 0.46f, 0.504f, 0.0f, 0.069f, 0.469f, 0.468f, 0.499f, 0.0f, 0.06f, 0.481f, 0.481f, 0.493f, 0.0f, 0.052f, 0.489f, 0.489f,
+ 0.487f, 0.0f, 0.044f, 0.492f, 0.492f, 0.481f, 0.0f, 0.037f, 0.501f, 0.5f, 0.474f, 0.0f, 0.029f, 0.513f, 0.513f, 0.467f, 0.0f, 0.022f, 0.521f, 0.521f,
+ 0.458f, 0.0f, 0.015f, 0.524f, 0.524f, 0.449f, 0.0f, 0.008f, 0.525f, 0.525f, 0.439f, 0.0f, 0.001f, 0.528f, 0.528f, 0.427f, 0.0f, -0.005f, 0.532f, 0.532f,
+ 0.416f, 0.0f, -0.011f, 0.533f, 0.533f, 0.401f, 0.0f, -0.015f, 0.537f, 0.537f, 0.386f, 0.0f, -0.018f, 0.539f, 0.539f, 0.371f, 0.0f, -0.02f, 0.538f, 0.538f,
+ 0.356f, 0.0f, -0.021f, 0.543f, 0.543f, 0.341f, 0.0f, -0.023f, 0.543f, 0.543f, 0.326f, 0.0f, -0.023f, 0.543f, 0.543f, 0.312f, 0.0f, -0.022f, 0.543f, 0.543f,
+ 0.298f, 0.0f, -0.018f, 0.543f, 0.543f, 0.286f, 0.0f, -0.014f, 0.543f, 0.543f, 0.273f, 0.0f, -0.006f, 0.543f, 0.543f, 0.26f, 0.0f, 0.004f, 0.543f, 0.543f,
+ 0.247f, 0.0f, 0.013f, 0.543f, 0.543f, 0.235f, 0.0f, 0.022f, 0.543f, 0.543f, 0.225f, 0.0f, 0.033f, 0.543f, 0.543f, 0.215f, 0.0f, 0.045f, 0.542f, 0.542f,
+ 0.206f, 0.0f, 0.061f, 0.54f, 0.54f, 0.199f, 0.0f, 0.078f, 0.542f, 0.542f, 0.193f, 0.0f, 0.094f, 0.542f, 0.542f, 0.189f, -0.0f, 0.109f, 0.541f, 0.541f,
+ 0.186f, -0.0f, 0.119f, 0.542f, 0.542f, 0.185f, -0.0f, 0.127f, 0.542f, 0.542f, 0.184f, -0.0f, 0.135f, 0.542f, 0.542f, 0.184f, -0.0f, 0.142f, 0.542f, 0.542f,
+ 0.183f, -0.0f, 0.149f, 0.541f, 0.541f, 0.183f, -0.0f, 0.156f, 0.538f, 0.538f, 0.183f, -0.0f, 0.163f, 0.539f, 0.539f, 0.183f, -0.0f, 0.17f, 0.54f, 0.54f,
+ 0.183f, 0.0f, 0.177f, 0.54f, 0.54f, 0.183f, 0.0f, 0.184f, 0.54f, 0.54f, 0.183f, 0.0f, 0.191f, 0.54f, 0.54f, 0.184f, 0.0f, 0.196f, 0.539f, 0.539f,
+ 0.184f, 0.0f, 0.204f, 0.518f, 0.518f,
+};
+
+static const float data14[45 * GP_PRIM_DATABUF_SIZE] = {
+ -0.096f, -0.0f, -0.305f, 0.01f, 0.01f, -0.09f, -0.0f, -0.313f, 0.121f, 0.362f, -0.086f, -0.0f, -0.318f, 0.179f, 0.368f, -0.081f, -0.0f, -0.325f, 0.234f, 0.37f,
+ -0.075f, -0.0f, -0.331f, 0.272f, 0.37f, -0.068f, -0.0f, -0.338f, 0.302f, 0.371f, -0.061f, -0.0f, -0.345f, 0.324f, 0.374f, -0.053f, -0.0f, -0.352f, 0.34f, 0.377f,
+ -0.044f, -0.0f, -0.358f, 0.352f, 0.378f, -0.035f, -0.0f, -0.362f, 0.362f, 0.377f, -0.026f, -0.0f, -0.366f, 0.37f, 0.378f, -0.018f, -0.0f, -0.368f, 0.377f, 0.378f,
+ -0.009f, -0.0f, -0.369f, 0.383f, 0.376f, -0.001f, -0.0f, -0.369f, 0.389f, 0.369f, 0.007f, -0.0f, -0.368f, 0.395f, 0.364f, 0.015f, -0.0f, -0.367f, 0.4f, 0.388f,
+ 0.023f, -0.0f, -0.365f, 0.405f, 0.41f, 0.03f, -0.0f, -0.363f, 0.41f, 0.429f, 0.038f, -0.0f, -0.36f, 0.414f, 0.438f, 0.044f, -0.0f, -0.357f, 0.417f, 0.441f,
+ 0.05f, -0.0f, -0.355f, 0.419f, 0.444f, 0.055f, -0.0f, -0.352f, 0.42f, 0.441f, 0.06f, -0.0f, -0.349f, 0.421f, 0.445f, 0.063f, -0.0f, -0.347f, 0.421f, 0.446f,
+ 0.065f, -0.0f, -0.344f, 0.42f, 0.443f, 0.065f, -0.0f, -0.342f, 0.42f, 0.437f, 0.065f, -0.0f, -0.341f, 0.419f, 0.413f, 0.063f, -0.0f, -0.339f, 0.418f, 0.404f,
+ 0.061f, -0.0f, -0.338f, 0.418f, 0.403f, 0.057f, -0.0f, -0.337f, 0.418f, 0.402f, 0.052f, -0.0f, -0.337f, 0.418f, 0.407f, 0.046f, -0.0f, -0.337f, 0.419f, 0.411f,
+ 0.04f, 0.0f, -0.336f, 0.42f, 0.416f, 0.032f, 0.0f, -0.337f, 0.422f, 0.421f, 0.023f, 0.0f, -0.339f, 0.424f, 0.425f, 0.014f, 0.0f, -0.34f, 0.426f, 0.427f,
+ 0.003f, 0.0f, -0.341f, 0.428f, 0.427f, -0.007f, 0.0f, -0.341f, 0.43f, 0.433f, -0.018f, 0.0f, -0.339f, 0.432f, 0.437f, -0.027f, 0.0f, -0.335f, 0.434f, 0.438f,
+ -0.037f, 0.0f, -0.33f, 0.435f, 0.437f, -0.046f, -0.0f, -0.326f, 0.436f, 0.438f, -0.055f, -0.0f, -0.321f, 0.436f, 0.44f, -0.062f, -0.0f, -0.316f, 0.437f, 0.439f,
+ -0.073f, -0.0f, -0.31f, 0.437f, 0.437f,
+};
+
+static const float data16[84 * GP_PRIM_DATABUF_SIZE] = {
+ 0.737f, 0.0f, 0.177f, 0.148f, 0.148f, 0.735f, 0.0f, 0.164f, 0.214f, 0.39f, 0.734f, 0.0f, 0.155f, 0.254f, 0.402f, 0.732f, 0.0f, 0.143f, 0.295f, 0.413f,
+ 0.73f, 0.0f, 0.132f, 0.328f, 0.415f, 0.728f, 0.0f, 0.121f, 0.355f, 0.415f, 0.726f, 0.0f, 0.109f, 0.375f, 0.416f, 0.724f, 0.0f, 0.097f, 0.39f, 0.417f,
+ 0.721f, 0.0f, 0.086f, 0.401f, 0.418f, 0.719f, 0.0f, 0.074f, 0.408f, 0.419f, 0.716f, 0.0f, 0.062f, 0.413f, 0.42f, 0.713f, 0.0f, 0.05f, 0.416f, 0.42f,
+ 0.71f, 0.0f, 0.039f, 0.418f, 0.421f, 0.707f, 0.0f, 0.028f, 0.42f, 0.421f, 0.703f, 0.0f, 0.017f, 0.421f, 0.422f, 0.7f, 0.0f, 0.006f, 0.421f, 0.422f,
+ 0.696f, 0.0f, -0.005f, 0.422f, 0.422f, 0.693f, 0.0f, -0.015f, 0.422f, 0.422f, 0.689f, 0.0f, -0.025f, 0.423f, 0.423f, 0.685f, 0.0f, -0.034f, 0.423f, 0.423f,
+ 0.681f, 0.0f, -0.044f, 0.423f, 0.423f, 0.677f, 0.0f, -0.053f, 0.423f, 0.423f, 0.672f, 0.0f, -0.062f, 0.423f, 0.423f, 0.668f, 0.0f, -0.071f, 0.422f, 0.424f,
+ 0.662f, 0.0f, -0.08f, 0.422f, 0.424f, 0.657f, 0.0f, -0.088f, 0.422f, 0.422f, 0.651f, 0.0f, -0.095f, 0.421f, 0.419f, 0.645f, 0.0f, -0.103f, 0.42f, 0.419f,
+ 0.638f, 0.0f, -0.109f, 0.42f, 0.419f, 0.631f, 0.0f, -0.115f, 0.419f, 0.419f, 0.624f, 0.0f, -0.12f, 0.419f, 0.419f, 0.617f, 0.0f, -0.125f, 0.419f, 0.419f,
+ 0.61f, 0.0f, -0.129f, 0.418f, 0.418f, 0.602f, 0.0f, -0.133f, 0.418f, 0.416f, 0.594f, 0.0f, -0.137f, 0.417f, 0.416f, 0.587f, 0.0f, -0.14f, 0.417f, 0.415f,
+ 0.579f, 0.0f, -0.142f, 0.417f, 0.416f, 0.571f, 0.0f, -0.144f, 0.417f, 0.415f, 0.564f, 0.0f, -0.145f, 0.417f, 0.416f, 0.556f, 0.0f, -0.146f, 0.417f, 0.415f,
+ 0.549f, 0.0f, -0.146f, 0.417f, 0.415f, 0.541f, 0.0f, -0.146f, 0.417f, 0.415f, 0.535f, 0.0f, -0.145f, 0.417f, 0.416f, 0.53f, 0.0f, -0.143f, 0.418f, 0.418f,
+ 0.526f, 0.0f, -0.14f, 0.418f, 0.418f, 0.524f, 0.0f, -0.136f, 0.42f, 0.418f, 0.524f, 0.0f, -0.132f, 0.422f, 0.416f, 0.527f, 0.0f, -0.126f, 0.424f, 0.424f,
+ 0.531f, 0.0f, -0.121f, 0.427f, 0.428f, 0.536f, 0.0f, -0.115f, 0.43f, 0.433f, 0.542f, 0.0f, -0.109f, 0.433f, 0.436f, 0.548f, 0.0f, -0.102f, 0.435f, 0.436f,
+ 0.555f, 0.0f, -0.095f, 0.436f, 0.437f, 0.562f, 0.0f, -0.088f, 0.437f, 0.438f, 0.568f, 0.0f, -0.081f, 0.437f, 0.438f, 0.575f, 0.0f, -0.073f, 0.438f, 0.438f,
+ 0.581f, 0.0f, -0.065f, 0.438f, 0.438f, 0.587f, 0.0f, -0.058f, 0.438f, 0.438f, 0.593f, 0.0f, -0.05f, 0.438f, 0.438f, 0.599f, 0.0f, -0.041f, 0.438f, 0.438f,
+ 0.605f, 0.0f, -0.033f, 0.438f, 0.438f, 0.61f, 0.0f, -0.024f, 0.438f, 0.438f, 0.615f, 0.0f, -0.015f, 0.438f, 0.438f, 0.621f, 0.0f, -0.006f, 0.438f, 0.438f,
+ 0.626f, 0.0f, 0.004f, 0.438f, 0.438f, 0.631f, 0.0f, 0.013f, 0.437f, 0.438f, 0.636f, 0.0f, 0.023f, 0.436f, 0.438f, 0.641f, 0.0f, 0.032f, 0.434f, 0.438f,
+ 0.647f, 0.0f, 0.042f, 0.432f, 0.437f, 0.652f, 0.0f, 0.051f, 0.431f, 0.429f, 0.657f, 0.0f, 0.06f, 0.429f, 0.426f, 0.662f, 0.0f, 0.069f, 0.427f, 0.425f,
+ 0.668f, 0.0f, 0.078f, 0.425f, 0.425f, 0.673f, 0.0f, 0.087f, 0.423f, 0.424f, 0.678f, 0.0f, 0.095f, 0.42f, 0.422f, 0.683f, 0.0f, 0.104f, 0.416f, 0.42f,
+ 0.688f, 0.0f, 0.112f, 0.411f, 0.421f, 0.693f, 0.0f, 0.12f, 0.403f, 0.417f, 0.698f, 0.0f, 0.128f, 0.394f, 0.411f, 0.702f, 0.0f, 0.135f, 0.382f, 0.404f,
+ 0.707f, 0.0f, 0.143f, 0.369f, 0.388f, 0.711f, 0.0f, 0.15f, 0.352f, 0.371f, 0.714f, 0.0f, 0.155f, 0.338f, 0.352f, 0.719f, 0.0f, 0.164f, 0.315f, 0.315f,
+};
+
+static const float data15[44 * GP_PRIM_DATABUF_SIZE] = {
+ -0.085f, 0.0f, -0.816f, 0.138f, 0.138f, -0.079f, 0.0f, -0.825f, 0.246f, 0.309f, -0.074f, 0.0f, -0.832f, 0.302f, 0.34f, -0.067f, 0.0f, -0.84f, 0.335f, 0.352f,
+ -0.059f, 0.0f, -0.848f, 0.357f, 0.374f, -0.05f, 0.0f, -0.855f, 0.371f, 0.378f, -0.041f, 0.0f, -0.861f, 0.382f, 0.383f, -0.031f, 0.0f, -0.866f, 0.391f, 0.396f,
+ -0.021f, 0.0f, -0.871f, 0.398f, 0.401f, -0.011f, 0.0f, -0.874f, 0.404f, 0.407f, -0.001f, 0.0f, -0.877f, 0.409f, 0.411f, 0.01f, 0.0f, -0.878f, 0.415f, 0.412f,
+ 0.02f, 0.0f, -0.878f, 0.422f, 0.417f, 0.031f, 0.0f, -0.878f, 0.43f, 0.421f, 0.042f, 0.0f, -0.876f, 0.438f, 0.437f, 0.052f, 0.0f, -0.873f, 0.445f, 0.451f,
+ 0.062f, 0.0f, -0.868f, 0.451f, 0.459f, 0.071f, 0.0f, -0.863f, 0.456f, 0.463f, 0.08f, 0.0f, -0.857f, 0.46f, 0.465f, 0.087f, 0.0f, -0.85f, 0.462f, 0.465f,
+ 0.094f, 0.0f, -0.842f, 0.461f, 0.465f, 0.098f, 0.0f, -0.835f, 0.458f, 0.467f, 0.101f, 0.0f, -0.827f, 0.451f, 0.457f, 0.103f, 0.0f, -0.82f, 0.436f, 0.451f,
+ 0.102f, 0.0f, -0.815f, 0.422f, 0.418f, 0.1f, 0.0f, -0.811f, 0.419f, 0.378f, 0.096f, 0.0f, -0.814f, 0.436f, 0.447f, 0.089f, 0.0f, -0.817f, 0.454f, 0.465f,
+ 0.082f, 0.0f, -0.821f, 0.465f, 0.47f, 0.072f, 0.0f, -0.825f, 0.473f, 0.477f, 0.061f, 0.0f, -0.828f, 0.477f, 0.479f, 0.049f, 0.0f, -0.832f, 0.48f, 0.485f,
+ 0.036f, 0.0f, -0.834f, 0.483f, 0.48f, 0.023f, 0.0f, -0.836f, 0.484f, 0.485f, 0.01f, 0.0f, -0.838f, 0.486f, 0.487f, -0.003f, 0.0f, -0.84f, 0.486f, 0.488f,
+ -0.016f, 0.0f, -0.84f, 0.486f, 0.489f, -0.027f, 0.0f, -0.84f, 0.485f, 0.485f, -0.039f, 0.0f, -0.839f, 0.484f, 0.484f, -0.049f, 0.0f, -0.837f, 0.483f, 0.485f,
+ -0.058f, 0.0f, -0.834f, 0.48f, 0.481f, -0.066f, 0.0f, -0.83f, 0.473f, 0.479f, -0.072f, 0.0f, -0.827f, 0.462f, 0.472f, -0.081f, 0.0f, -0.823f, 0.442f, 0.442f,
+};
+
+static const float data17[56 * GP_PRIM_DATABUF_SIZE] = {
+ -1.007f, -0.0f, 0.183f, 0.022f, 0.022f, -1.003f, -0.0f, 0.181f, 0.192f, 0.436f, -0.998f, -0.0f, 0.18f, 0.28f, 0.451f, -0.99f, -0.0f, 0.178f, 0.355f, 0.459f,
+ -0.98f, -0.0f, 0.175f, 0.402f, 0.464f, -0.967f, -0.0f, 0.169f, 0.432f, 0.467f, -0.952f, -0.0f, 0.152f, 0.449f, 0.468f, -0.943f, 0.0f, 0.138f, 0.459f, 0.469f,
+ -0.939f, 0.0f, 0.128f, 0.464f, 0.469f, -0.934f, 0.0f, 0.119f, 0.467f, 0.47f, -0.929f, 0.0f, 0.11f, 0.469f, 0.47f, -0.924f, 0.0f, 0.101f, 0.47f, 0.47f,
+ -0.919f, 0.0f, 0.092f, 0.47f, 0.471f, -0.913f, 0.0f, 0.082f, 0.471f, 0.471f, -0.908f, 0.0f, 0.072f, 0.471f, 0.471f, -0.903f, 0.0f, 0.063f, 0.472f, 0.472f,
+ -0.897f, 0.0f, 0.053f, 0.472f, 0.472f, -0.892f, 0.0f, 0.044f, 0.473f, 0.473f, -0.886f, 0.0f, 0.035f, 0.473f, 0.473f, -0.881f, 0.0f, 0.026f, 0.473f, 0.473f,
+ -0.876f, 0.0f, 0.018f, 0.473f, 0.473f, -0.87f, 0.0f, 0.012f, 0.472f, 0.473f, -0.865f, 0.0f, 0.006f, 0.47f, 0.473f, -0.86f, 0.0f, 0.003f, 0.468f, 0.473f,
+ -0.855f, 0.0f, 0.001f, 0.466f, 0.469f, -0.85f, 0.0f, 0.001f, 0.463f, 0.469f, -0.846f, 0.0f, 0.003f, 0.46f, 0.45f, -0.843f, 0.0f, 0.008f, 0.458f, 0.454f,
+ -0.84f, 0.0f, 0.014f, 0.456f, 0.454f, -0.838f, 0.0f, 0.021f, 0.455f, 0.454f, -0.836f, 0.0f, 0.03f, 0.453f, 0.455f, -0.835f, 0.0f, 0.039f, 0.451f, 0.455f,
+ -0.835f, 0.0f, 0.049f, 0.449f, 0.453f, -0.836f, 0.0f, 0.059f, 0.447f, 0.445f, -0.837f, 0.0f, 0.068f, 0.445f, 0.441f, -0.84f, 0.0f, 0.078f, 0.443f, 0.44f,
+ -0.843f, 0.0f, 0.087f, 0.442f, 0.44f, -0.846f, 0.0f, 0.095f, 0.442f, 0.44f, -0.851f, -0.0f, 0.103f, 0.441f, 0.441f, -0.855f, -0.0f, 0.111f, 0.441f, 0.44f,
+ -0.86f, -0.0f, 0.119f, 0.441f, 0.441f, -0.865f, -0.0f, 0.127f, 0.441f, 0.441f, -0.871f, -0.0f, 0.134f, 0.441f, 0.441f, -0.877f, -0.0f, 0.141f, 0.441f, 0.441f,
+ -0.883f, -0.0f, 0.149f, 0.441f, 0.442f, -0.889f, -0.0f, 0.156f, 0.441f, 0.441f, -0.896f, -0.0f, 0.163f, 0.441f, 0.442f, -0.904f, -0.0f, 0.169f, 0.442f, 0.441f,
+ -0.913f, -0.0f, 0.176f, 0.442f, 0.441f, -0.925f, -0.0f, 0.183f, 0.443f, 0.441f, -0.941f, -0.0f, 0.19f, 0.444f, 0.442f, -0.956f, -0.0f, 0.195f, 0.446f, 0.443f,
+ -0.971f, -0.0f, 0.198f, 0.448f, 0.443f, -0.983f, -0.0f, 0.198f, 0.451f, 0.452f, -0.992f, -0.0f, 0.198f, 0.454f, 0.456f, -1.001f, 0.0f, 0.196f, 0.457f, 0.457f,
+};
+
+static const float data18[59 * GP_PRIM_DATABUF_SIZE] = {
+ 0.782f, 0.0f, 0.099f, 0.04f, 0.04f, 0.779f, 0.0f, 0.088f, 0.108f, 0.34f, 0.777f, 0.0f, 0.08f, 0.149f, 0.35f, 0.774f, 0.0f, 0.071f, 0.194f, 0.352f,
+ 0.772f, 0.0f, 0.062f, 0.231f, 0.352f, 0.771f, 0.0f, 0.053f, 0.263f, 0.353f, 0.769f, 0.0f, 0.044f, 0.289f, 0.353f, 0.768f, 0.0f, 0.036f, 0.31f, 0.353f,
+ 0.767f, 0.0f, 0.029f, 0.327f, 0.353f, 0.767f, 0.0f, 0.023f, 0.341f, 0.353f, 0.767f, 0.0f, 0.017f, 0.353f, 0.353f, 0.768f, 0.0f, 0.013f, 0.363f, 0.353f,
+ 0.769f, 0.0f, 0.01f, 0.373f, 0.353f, 0.771f, 0.0f, 0.009f, 0.382f, 0.351f, 0.773f, 0.0f, 0.008f, 0.39f, 0.393f, 0.776f, 0.0f, 0.009f, 0.399f, 0.41f,
+ 0.779f, 0.0f, 0.011f, 0.407f, 0.425f, 0.783f, 0.0f, 0.015f, 0.415f, 0.434f, 0.787f, 0.0f, 0.019f, 0.423f, 0.44f, 0.792f, 0.0f, 0.024f, 0.429f, 0.441f,
+ 0.797f, 0.0f, 0.03f, 0.435f, 0.444f, 0.802f, 0.0f, 0.037f, 0.441f, 0.447f, 0.807f, 0.0f, 0.044f, 0.445f, 0.453f, 0.813f, 0.0f, 0.051f, 0.449f, 0.457f,
+ 0.819f, 0.0f, 0.058f, 0.452f, 0.458f, 0.825f, 0.0f, 0.066f, 0.455f, 0.46f, 0.831f, 0.0f, 0.074f, 0.457f, 0.462f, 0.838f, 0.0f, 0.082f, 0.459f, 0.462f,
+ 0.845f, 0.0f, 0.09f, 0.461f, 0.462f, 0.852f, 0.0f, 0.098f, 0.462f, 0.463f, 0.859f, 0.0f, 0.106f, 0.463f, 0.464f, 0.867f, 0.0f, 0.113f, 0.464f, 0.464f,
+ 0.874f, 0.0f, 0.121f, 0.465f, 0.465f, 0.882f, 0.0f, 0.129f, 0.465f, 0.465f, 0.889f, 0.0f, 0.136f, 0.466f, 0.466f, 0.897f, 0.0f, 0.143f, 0.466f, 0.467f,
+ 0.904f, 0.0f, 0.15f, 0.467f, 0.466f, 0.911f, 0.0f, 0.157f, 0.467f, 0.467f, 0.916f, 0.0f, 0.163f, 0.468f, 0.468f, 0.921f, 0.0f, 0.169f, 0.468f, 0.469f,
+ 0.924f, 0.0f, 0.173f, 0.468f, 0.469f, 0.926f, 0.0f, 0.177f, 0.469f, 0.468f, 0.925f, 0.0f, 0.18f, 0.469f, 0.468f, 0.922f, 0.0f, 0.181f, 0.469f, 0.469f,
+ 0.918f, 0.0f, 0.181f, 0.469f, 0.469f, 0.912f, 0.0f, 0.18f, 0.469f, 0.469f, 0.905f, 0.0f, 0.178f, 0.468f, 0.47f, 0.898f, 0.0f, 0.175f, 0.466f, 0.471f,
+ 0.89f, 0.0f, 0.172f, 0.462f, 0.469f, 0.882f, 0.0f, 0.168f, 0.454f, 0.468f, 0.874f, 0.0f, 0.164f, 0.442f, 0.467f, 0.866f, 0.0f, 0.159f, 0.423f, 0.467f,
+ 0.858f, 0.0f, 0.154f, 0.398f, 0.468f, 0.851f, 0.0f, 0.149f, 0.366f, 0.468f, 0.844f, 0.0f, 0.144f, 0.326f, 0.469f, 0.837f, 0.0f, 0.139f, 0.282f, 0.469f,
+ 0.83f, 0.0f, 0.134f, 0.231f, 0.467f, 0.824f, 0.0f, 0.13f, 0.184f, 0.415f, 0.816f, 0.0f, 0.124f, 0.111f, 0.111f,
+};
+
+static const float data19[100 * GP_PRIM_DATABUF_SIZE] = {
+ -0.279f, 0.0f, 0.568f, 0.154f, 0.154f, -0.266f, 0.0f, 0.569f, 0.249f, 0.318f, -0.258f, 0.0f, 0.57f, 0.296f, 0.357f, -0.248f, 0.0f, 0.571f, 0.337f, 0.383f,
+ -0.238f, 0.0f, 0.571f, 0.363f, 0.396f, -0.229f, 0.0f, 0.571f, 0.381f, 0.403f, -0.219f, 0.0f, 0.57f, 0.392f, 0.407f, -0.209f, 0.0f, 0.568f, 0.399f, 0.407f,
+ -0.2f, 0.0f, 0.566f, 0.403f, 0.408f, -0.19f, 0.0f, 0.563f, 0.406f, 0.41f, -0.181f, 0.0f, 0.559f, 0.407f, 0.41f, -0.171f, 0.0f, 0.555f, 0.409f, 0.41f,
+ -0.161f, 0.0f, 0.551f, 0.409f, 0.411f, -0.152f, 0.0f, 0.546f, 0.41f, 0.411f, -0.142f, 0.0f, 0.542f, 0.41f, 0.412f, -0.132f, 0.0f, 0.537f, 0.411f, 0.411f,
+ -0.122f, 0.0f, 0.533f, 0.411f, 0.411f, -0.112f, 0.0f, 0.528f, 0.411f, 0.412f, -0.102f, 0.0f, 0.524f, 0.411f, 0.412f, -0.092f, 0.0f, 0.519f, 0.41f, 0.412f,
+ -0.081f, 0.0f, 0.515f, 0.407f, 0.411f, -0.071f, 0.0f, 0.511f, 0.403f, 0.408f, -0.061f, 0.0f, 0.507f, 0.399f, 0.401f, -0.051f, 0.0f, 0.503f, 0.394f, 0.395f,
+ -0.041f, 0.0f, 0.499f, 0.39f, 0.388f, -0.031f, 0.0f, 0.495f, 0.386f, 0.383f, -0.021f, 0.0f, 0.491f, 0.383f, 0.38f, -0.011f, 0.0f, 0.488f, 0.381f, 0.378f,
+ -0.001f, 0.0f, 0.486f, 0.379f, 0.377f, 0.009f, 0.0f, 0.484f, 0.378f, 0.377f, 0.019f, 0.0f, 0.483f, 0.377f, 0.375f, 0.03f, 0.0f, 0.482f, 0.377f, 0.375f,
+ 0.041f, 0.0f, 0.482f, 0.378f, 0.376f, 0.051f, 0.0f, 0.483f, 0.379f, 0.376f, 0.062f, 0.0f, 0.484f, 0.381f, 0.376f, 0.073f, 0.0f, 0.486f, 0.385f, 0.379f,
+ 0.085f, 0.0f, 0.488f, 0.389f, 0.382f, 0.096f, 0.0f, 0.491f, 0.395f, 0.392f, 0.108f, 0.0f, 0.494f, 0.402f, 0.4f, 0.12f, 0.0f, 0.497f, 0.409f, 0.409f,
+ 0.132f, 0.0f, 0.501f, 0.415f, 0.416f, 0.144f, 0.0f, 0.505f, 0.421f, 0.427f, 0.157f, 0.0f, 0.509f, 0.425f, 0.43f, 0.17f, 0.0f, 0.513f, 0.429f, 0.433f,
+ 0.181f, 0.0f, 0.517f, 0.431f, 0.433f, 0.192f, 0.0f, 0.52f, 0.433f, 0.434f, 0.201f, 0.0f, 0.522f, 0.433f, 0.435f, 0.208f, 0.0f, 0.524f, 0.433f, 0.435f,
+ 0.213f, 0.0f, 0.524f, 0.432f, 0.436f, 0.216f, 0.0f, 0.523f, 0.431f, 0.435f, 0.217f, 0.0f, 0.521f, 0.43f, 0.426f, 0.215f, 0.0f, 0.518f, 0.429f, 0.427f,
+ 0.213f, 0.0f, 0.515f, 0.428f, 0.427f, 0.208f, 0.0f, 0.511f, 0.428f, 0.427f, 0.203f, 0.0f, 0.506f, 0.428f, 0.427f, 0.196f, 0.0f, 0.502f, 0.428f, 0.427f,
+ 0.189f, 0.0f, 0.497f, 0.428f, 0.427f, 0.181f, 0.0f, 0.492f, 0.428f, 0.427f, 0.173f, 0.0f, 0.487f, 0.428f, 0.428f, 0.163f, 0.0f, 0.482f, 0.429f, 0.428f,
+ 0.154f, 0.0f, 0.477f, 0.429f, 0.429f, 0.145f, 0.0f, 0.472f, 0.43f, 0.43f, 0.135f, 0.0f, 0.467f, 0.431f, 0.431f, 0.125f, 0.0f, 0.462f, 0.432f, 0.43f,
+ 0.116f, 0.0f, 0.457f, 0.433f, 0.431f, 0.106f, 0.0f, 0.453f, 0.435f, 0.434f, 0.096f, 0.0f, 0.448f, 0.436f, 0.436f, 0.086f, 0.0f, 0.444f, 0.437f, 0.438f,
+ 0.076f, 0.0f, 0.44f, 0.438f, 0.44f, 0.065f, 0.0f, 0.436f, 0.439f, 0.441f, 0.055f, 0.0f, 0.433f, 0.44f, 0.441f, 0.044f, 0.0f, 0.431f, 0.441f, 0.442f,
+ 0.033f, 0.0f, 0.429f, 0.441f, 0.442f, 0.022f, 0.0f, 0.427f, 0.441f, 0.442f, 0.011f, 0.0f, 0.426f, 0.442f, 0.443f, -0.0f, 0.0f, 0.426f, 0.442f, 0.442f,
+ -0.011f, 0.0f, 0.426f, 0.442f, 0.442f, -0.022f, 0.0f, 0.427f, 0.442f, 0.442f, -0.033f, 0.0f, 0.429f, 0.442f, 0.442f, -0.042f, 0.0f, 0.432f, 0.441f, 0.442f,
+ -0.052f, 0.0f, 0.435f, 0.441f, 0.441f, -0.061f, 0.0f, 0.439f, 0.441f, 0.441f, -0.07f, 0.0f, 0.443f, 0.441f, 0.441f, -0.078f, 0.0f, 0.448f, 0.441f, 0.441f,
+ -0.087f, 0.0f, 0.453f, 0.441f, 0.442f, -0.095f, 0.0f, 0.458f, 0.441f, 0.441f, -0.104f, 0.0f, 0.463f, 0.44f, 0.44f, -0.113f, 0.0f, 0.468f, 0.44f, 0.44f,
+ -0.122f, 0.0f, 0.473f, 0.44f, 0.44f, -0.132f, 0.0f, 0.479f, 0.44f, 0.44f, -0.143f, 0.0f, 0.485f, 0.44f, 0.44f, -0.154f, 0.0f, 0.491f, 0.44f, 0.44f,
+ -0.165f, 0.0f, 0.498f, 0.44f, 0.44f, -0.176f, 0.0f, 0.504f, 0.439f, 0.439f, -0.187f, 0.0f, 0.51f, 0.435f, 0.44f, -0.198f, 0.0f, 0.516f, 0.424f, 0.44f,
+ -0.209f, 0.0f, 0.522f, 0.393f, 0.44f, -0.219f, 0.0f, 0.527f, 0.324f, 0.44f, -0.228f, 0.0f, 0.532f, 0.222f, 0.404f, -0.241f, 0.0f, 0.538f, 0.037f, 0.037f,
+};
+
+static const float data20[136 * GP_PRIM_DATABUF_SIZE] = {
+ 0.331f, 0.0f, -0.036f, 0.065f, 0.065f, 0.322f, 0.0f, -0.034f, 0.239f, 0.293f, 0.317f, 0.0f, -0.032f, 0.316f, 0.339f, 0.31f, 0.0f, -0.029f, 0.348f, 0.355f,
+ 0.302f, 0.0f, -0.027f, 0.364f, 0.368f, 0.295f, 0.0f, -0.023f, 0.373f, 0.374f, 0.287f, 0.0f, -0.02f, 0.381f, 0.381f, 0.279f, 0.0f, -0.015f, 0.388f, 0.391f,
+ 0.271f, 0.0f, -0.01f, 0.392f, 0.394f, 0.263f, 0.0f, -0.004f, 0.395f, 0.396f, 0.255f, 0.0f, 0.002f, 0.397f, 0.397f, 0.247f, 0.0f, 0.008f, 0.399f, 0.4f,
+ 0.239f, 0.0f, 0.016f, 0.401f, 0.401f, 0.232f, -0.0f, 0.024f, 0.404f, 0.404f, 0.226f, 0.0f, 0.031f, 0.406f, 0.407f, 0.221f, 0.0f, 0.038f, 0.409f, 0.409f,
+ 0.215f, 0.0f, 0.045f, 0.412f, 0.412f, 0.21f, 0.0f, 0.054f, 0.415f, 0.415f, 0.205f, 0.0f, 0.063f, 0.417f, 0.417f, 0.201f, 0.0f, 0.073f, 0.42f, 0.421f,
+ 0.197f, 0.0f, 0.083f, 0.421f, 0.421f, 0.193f, -0.0f, 0.094f, 0.423f, 0.423f, 0.19f, -0.0f, 0.104f, 0.424f, 0.424f, 0.187f, -0.0f, 0.114f, 0.424f, 0.425f,
+ 0.185f, -0.0f, 0.125f, 0.425f, 0.425f, 0.183f, -0.0f, 0.135f, 0.425f, 0.425f, 0.182f, -0.0f, 0.146f, 0.426f, 0.425f, 0.181f, -0.0f, 0.157f, 0.426f, 0.425f,
+ 0.18f, -0.0f, 0.168f, 0.426f, 0.426f, 0.18f, -0.0f, 0.179f, 0.427f, 0.427f, 0.181f, -0.0f, 0.189f, 0.427f, 0.427f, 0.182f, -0.0f, 0.199f, 0.427f, 0.427f,
+ 0.183f, -0.0f, 0.208f, 0.427f, 0.428f, 0.185f, -0.0f, 0.218f, 0.428f, 0.427f, 0.187f, -0.0f, 0.226f, 0.428f, 0.427f, 0.19f, -0.0f, 0.235f, 0.429f, 0.427f,
+ 0.192f, -0.0f, 0.243f, 0.43f, 0.428f, 0.196f, -0.0f, 0.252f, 0.431f, 0.431f, 0.199f, -0.0f, 0.26f, 0.431f, 0.432f, 0.203f, -0.0f, 0.268f, 0.432f, 0.433f,
+ 0.207f, -0.0f, 0.276f, 0.433f, 0.433f, 0.212f, -0.0f, 0.283f, 0.434f, 0.434f, 0.216f, -0.0f, 0.291f, 0.434f, 0.435f, 0.221f, -0.0f, 0.298f, 0.435f, 0.436f,
+ 0.227f, -0.0f, 0.305f, 0.435f, 0.435f, 0.232f, -0.0f, 0.311f, 0.436f, 0.436f, 0.238f, -0.0f, 0.317f, 0.436f, 0.436f, 0.243f, -0.0f, 0.323f, 0.436f, 0.436f,
+ 0.249f, -0.0f, 0.329f, 0.437f, 0.436f, 0.255f, -0.0f, 0.334f, 0.438f, 0.437f, 0.262f, -0.0f, 0.339f, 0.44f, 0.437f, 0.268f, -0.0f, 0.344f, 0.442f, 0.441f,
+ 0.274f, 0.0f, 0.348f, 0.444f, 0.446f, 0.281f, 0.0f, 0.352f, 0.445f, 0.447f, 0.287f, 0.0f, 0.355f, 0.446f, 0.447f, 0.293f, 0.0f, 0.358f, 0.446f, 0.447f,
+ 0.299f, 0.0f, 0.361f, 0.447f, 0.447f, 0.306f, 0.0f, 0.363f, 0.447f, 0.448f, 0.312f, 0.0f, 0.366f, 0.447f, 0.448f, 0.318f, 0.0f, 0.368f, 0.448f, 0.448f,
+ 0.325f, 0.0f, 0.369f, 0.448f, 0.448f, 0.331f, 0.0f, 0.371f, 0.448f, 0.448f, 0.338f, 0.0f, 0.372f, 0.448f, 0.448f, 0.345f, 0.0f, 0.372f, 0.448f, 0.448f,
+ 0.352f, 0.0f, 0.372f, 0.448f, 0.448f, 0.359f, 0.0f, 0.372f, 0.448f, 0.449f, 0.366f, 0.0f, 0.371f, 0.448f, 0.448f, 0.373f, 0.0f, 0.37f, 0.448f, 0.449f,
+ 0.38f, 0.0f, 0.369f, 0.449f, 0.449f, 0.387f, 0.0f, 0.367f, 0.449f, 0.449f, 0.393f, 0.0f, 0.365f, 0.449f, 0.449f, 0.4f, 0.0f, 0.363f, 0.449f, 0.45f,
+ 0.406f, 0.0f, 0.36f, 0.45f, 0.45f, 0.412f, -0.0f, 0.357f, 0.45f, 0.45f, 0.418f, -0.0f, 0.354f, 0.45f, 0.451f, 0.424f, -0.0f, 0.351f, 0.45f, 0.451f,
+ 0.43f, -0.0f, 0.347f, 0.45f, 0.451f, 0.436f, -0.0f, 0.343f, 0.45f, 0.451f, 0.443f, -0.0f, 0.339f, 0.45f, 0.45f, 0.449f, -0.0f, 0.334f, 0.45f, 0.451f,
+ 0.455f, -0.0f, 0.329f, 0.451f, 0.451f, 0.46f, -0.0f, 0.323f, 0.451f, 0.451f, 0.466f, -0.0f, 0.318f, 0.451f, 0.451f, 0.472f, -0.0f, 0.311f, 0.452f, 0.452f,
+ 0.477f, -0.0f, 0.305f, 0.452f, 0.453f, 0.482f, -0.0f, 0.298f, 0.452f, 0.453f, 0.487f, -0.0f, 0.291f, 0.453f, 0.453f, 0.492f, -0.0f, 0.284f, 0.453f, 0.453f,
+ 0.496f, -0.0f, 0.277f, 0.453f, 0.453f, 0.5f, -0.0f, 0.269f, 0.453f, 0.454f, 0.504f, -0.0f, 0.261f, 0.453f, 0.454f, 0.508f, -0.0f, 0.252f, 0.454f, 0.454f,
+ 0.511f, -0.0f, 0.244f, 0.454f, 0.454f, 0.514f, -0.0f, 0.235f, 0.454f, 0.455f, 0.517f, -0.0f, 0.225f, 0.454f, 0.455f, 0.519f, -0.0f, 0.216f, 0.454f, 0.455f,
+ 0.521f, -0.0f, 0.205f, 0.455f, 0.455f, 0.523f, -0.0f, 0.194f, 0.455f, 0.455f, 0.524f, -0.0f, 0.182f, 0.455f, 0.455f, 0.524f, -0.0f, 0.169f, 0.455f, 0.456f,
+ 0.524f, -0.0f, 0.157f, 0.455f, 0.456f, 0.523f, -0.0f, 0.145f, 0.455f, 0.456f, 0.522f, -0.0f, 0.133f, 0.455f, 0.456f, 0.52f, -0.0f, 0.122f, 0.456f, 0.456f,
+ 0.518f, -0.0f, 0.11f, 0.456f, 0.456f, 0.515f, -0.0f, 0.1f, 0.456f, 0.456f, 0.513f, -0.0f, 0.09f, 0.456f, 0.457f, 0.509f, -0.0f, 0.081f, 0.456f, 0.457f,
+ 0.506f, -0.0f, 0.072f, 0.457f, 0.457f, 0.502f, -0.0f, 0.064f, 0.457f, 0.457f, 0.498f, -0.0f, 0.056f, 0.457f, 0.457f, 0.494f, -0.0f, 0.049f, 0.457f, 0.457f,
+ 0.49f, -0.0f, 0.041f, 0.458f, 0.457f, 0.485f, -0.0f, 0.034f, 0.458f, 0.457f, 0.48f, -0.0f, 0.028f, 0.458f, 0.458f, 0.475f, -0.0f, 0.022f, 0.458f, 0.458f,
+ 0.47f, -0.0f, 0.016f, 0.458f, 0.458f, 0.465f, -0.0f, 0.011f, 0.459f, 0.458f, 0.46f, -0.0f, 0.006f, 0.459f, 0.458f, 0.454f, -0.0f, 0.001f, 0.46f, 0.459f,
+ 0.449f, 0.0f, -0.003f, 0.464f, 0.463f, 0.443f, 0.0f, -0.007f, 0.467f, 0.468f, 0.438f, 0.0f, -0.011f, 0.469f, 0.469f, 0.432f, 0.0f, -0.015f, 0.471f, 0.47f,
+ 0.426f, 0.0f, -0.018f, 0.477f, 0.478f, 0.42f, 0.0f, -0.021f, 0.478f, 0.478f, 0.414f, 0.0f, -0.024f, 0.478f, 0.478f, 0.408f, 0.0f, -0.027f, 0.479f, 0.479f,
+ 0.402f, 0.0f, -0.029f, 0.48f, 0.48f, 0.395f, 0.0f, -0.031f, 0.48f, 0.48f, 0.389f, 0.0f, -0.033f, 0.482f, 0.482f, 0.382f, 0.0f, -0.035f, 0.482f, 0.482f,
+ 0.376f, 0.0f, -0.036f, 0.482f, 0.482f, 0.369f, 0.0f, -0.037f, 0.48f, 0.482f, 0.364f, 0.0f, -0.037f, 0.457f, 0.485f, 0.356f, 0.0f, -0.038f, 0.32f, 0.32f,
+};
+
+static const float data21[353 * GP_PRIM_DATABUF_SIZE] = {
+ -0.382f, 0.0f, 0.397f, 0.0f, 1.0f, -0.386f, 0.0f, 0.394f, 0.0f, 1.0f, -0.389f, 0.0f, 0.392f, 0.0f, 1.0f, -0.392f, 0.0f, 0.39f, 0.0f, 1.0f,
+ -0.395f, 0.0f, 0.388f, 0.0f, 1.0f, -0.399f, 0.0f, 0.385f, 0.0f, 1.0f, -0.402f, 0.0f, 0.383f, 0.0f, 1.0f, -0.405f, 0.0f, 0.381f, 0.0f, 1.0f,
+ -0.408f, 0.0f, 0.379f, 0.0f, 1.0f, -0.411f, 0.0f, 0.377f, 0.0f, 1.0f, -0.414f, 0.0f, 0.375f, 0.0f, 1.0f, -0.417f, 0.0f, 0.372f, 0.0f, 1.0f,
+ -0.42f, 0.0f, 0.37f, 0.0f, 1.0f, -0.423f, 0.0f, 0.368f, 0.0f, 1.0f, -0.425f, 0.0f, 0.366f, 0.0f, 1.0f, -0.428f, 0.0f, 0.364f, 0.0f, 1.0f,
+ -0.431f, 0.0f, 0.362f, 0.0f, 1.0f, -0.433f, 0.0f, 0.359f, 0.0f, 1.0f, -0.436f, 0.0f, 0.357f, 0.0f, 1.0f, -0.438f, 0.0f, 0.355f, 0.0f, 1.0f,
+ -0.441f, 0.0f, 0.353f, 0.0f, 1.0f, -0.443f, 0.0f, 0.351f, 0.0f, 1.0f, -0.445f, 0.0f, 0.349f, 0.0f, 1.0f, -0.447f, 0.0f, 0.346f, 0.0f, 1.0f,
+ -0.45f, 0.0f, 0.344f, 0.0f, 1.0f, -0.452f, 0.0f, 0.342f, 0.0f, 1.0f, -0.454f, 0.0f, 0.34f, 0.0f, 1.0f, -0.456f, 0.0f, 0.337f, 0.0f, 1.0f,
+ -0.458f, 0.0f, 0.335f, 0.0f, 1.0f, -0.46f, 0.0f, 0.333f, 0.0f, 1.0f, -0.462f, 0.0f, 0.33f, 0.0f, 1.0f, -0.464f, 0.0f, 0.328f, 0.0f, 1.0f,
+ -0.466f, 0.0f, 0.326f, 0.0f, 1.0f, -0.468f, 0.0f, 0.323f, 0.0f, 1.0f, -0.47f, 0.0f, 0.321f, 0.0f, 1.0f, -0.472f, 0.0f, 0.319f, 0.0f, 1.0f,
+ -0.474f, 0.0f, 0.316f, 0.0f, 1.0f, -0.475f, 0.0f, 0.314f, 0.0f, 1.0f, -0.477f, 0.0f, 0.311f, 0.0f, 1.0f, -0.479f, 0.0f, 0.309f, 0.0f, 1.0f,
+ -0.481f, 0.0f, 0.307f, 0.0f, 1.0f, -0.482f, 0.0f, 0.304f, 0.0f, 1.0f, -0.484f, 0.0f, 0.302f, 0.0f, 1.0f, -0.486f, 0.0f, 0.299f, 0.0f, 1.0f,
+ -0.487f, 0.0f, 0.297f, 0.0f, 1.0f, -0.489f, 0.0f, 0.294f, 0.0f, 1.0f, -0.49f, 0.0f, 0.292f, 0.0f, 1.0f, -0.492f, 0.0f, 0.289f, 0.0f, 1.0f,
+ -0.494f, 0.0f, 0.286f, 0.0f, 1.0f, -0.495f, 0.0f, 0.284f, 0.0f, 1.0f, -0.497f, 0.0f, 0.281f, 0.0f, 1.0f, -0.498f, 0.0f, 0.279f, 0.001f, 1.0f,
+ -0.499f, 0.0f, 0.276f, 0.001f, 1.0f, -0.501f, 0.0f, 0.273f, 0.002f, 1.0f, -0.502f, 0.0f, 0.271f, 0.003f, 1.0f, -0.504f, 0.0f, 0.268f, 0.005f, 1.0f,
+ -0.505f, 0.0f, 0.265f, 0.008f, 1.0f, -0.506f, 0.0f, 0.262f, 0.011f, 1.0f, -0.508f, 0.0f, 0.259f, 0.016f, 1.0f, -0.509f, 0.0f, 0.256f, 0.021f, 1.0f,
+ -0.51f, 0.0f, 0.254f, 0.027f, 1.0f, -0.512f, 0.0f, 0.251f, 0.035f, 1.0f, -0.513f, 0.0f, 0.248f, 0.043f, 1.0f, -0.514f, 0.0f, 0.245f, 0.053f, 1.0f,
+ -0.515f, 0.0f, 0.242f, 0.064f, 1.0f, -0.516f, 0.0f, 0.239f, 0.076f, 1.0f, -0.517f, 0.0f, 0.235f, 0.09f, 1.0f, -0.519f, 0.0f, 0.232f, 0.105f, 1.0f,
+ -0.52f, 0.0f, 0.229f, 0.122f, 1.0f, -0.521f, 0.0f, 0.226f, 0.14f, 1.0f, -0.521f, 0.0f, 0.222f, 0.159f, 1.0f, -0.522f, 0.0f, 0.219f, 0.179f, 1.0f,
+ -0.523f, 0.0f, 0.216f, 0.2f, 1.0f, -0.524f, 0.0f, 0.212f, 0.221f, 1.0f, -0.525f, 0.0f, 0.209f, 0.243f, 1.0f, -0.526f, 0.0f, 0.205f, 0.265f, 1.0f,
+ -0.526f, 0.0f, 0.202f, 0.286f, 1.0f, -0.527f, 0.0f, 0.198f, 0.306f, 1.0f, -0.527f, 0.0f, 0.195f, 0.326f, 1.0f, -0.528f, 0.0f, 0.191f, 0.345f, 1.0f,
+ -0.528f, 0.0f, 0.187f, 0.363f, 1.0f, -0.529f, 0.0f, 0.184f, 0.38f, 1.0f, -0.529f, 0.0f, 0.18f, 0.395f, 1.0f, -0.529f, 0.0f, 0.176f, 0.41f, 1.0f,
+ -0.53f, 0.0f, 0.173f, 0.424f, 1.0f, -0.53f, 0.0f, 0.169f, 0.438f, 1.0f, -0.53f, 0.0f, 0.165f, 0.452f, 1.0f, -0.53f, 0.0f, 0.161f, 0.465f, 1.0f,
+ -0.53f, 0.0f, 0.157f, 0.478f, 1.0f, -0.53f, 0.0f, 0.154f, 0.492f, 1.0f, -0.53f, 0.0f, 0.15f, 0.505f, 1.0f, -0.53f, 0.0f, 0.146f, 0.517f, 1.0f,
+ -0.53f, 0.0f, 0.142f, 0.53f, 1.0f, -0.529f, 0.0f, 0.138f, 0.542f, 1.0f, -0.529f, 0.0f, 0.134f, 0.553f, 1.0f, -0.528f, 0.0f, 0.13f, 0.564f, 1.0f,
+ -0.528f, 0.0f, 0.127f, 0.574f, 1.0f, -0.527f, 0.0f, 0.123f, 0.583f, 1.0f, -0.527f, 0.0f, 0.119f, 0.592f, 1.0f, -0.526f, 0.0f, 0.115f, 0.6f, 1.0f,
+ -0.526f, 0.0f, 0.111f, 0.608f, 1.0f, -0.525f, 0.0f, 0.108f, 0.615f, 1.0f, -0.524f, 0.0f, 0.104f, 0.622f, 1.0f, -0.523f, 0.0f, 0.1f, 0.628f, 1.0f,
+ -0.522f, 0.0f, 0.097f, 0.635f, 1.0f, -0.521f, 0.0f, 0.093f, 0.641f, 1.0f, -0.52f, 0.0f, 0.089f, 0.647f, 1.0f, -0.519f, 0.0f, 0.086f, 0.653f, 1.0f,
+ -0.518f, 0.0f, 0.082f, 0.659f, 1.0f, -0.517f, 0.0f, 0.079f, 0.664f, 1.0f, -0.515f, 0.0f, 0.075f, 0.67f, 1.0f, -0.514f, 0.0f, 0.072f, 0.675f, 1.0f,
+ -0.513f, 0.0f, 0.069f, 0.68f, 1.0f, -0.511f, 0.0f, 0.065f, 0.685f, 1.0f, -0.51f, 0.0f, 0.062f, 0.69f, 1.0f, -0.509f, 0.0f, 0.059f, 0.695f, 1.0f,
+ -0.507f, 0.0f, 0.056f, 0.7f, 1.0f, -0.505f, 0.0f, 0.053f, 0.704f, 1.0f, -0.504f, 0.0f, 0.049f, 0.709f, 1.0f, -0.502f, 0.0f, 0.046f, 0.714f, 1.0f,
+ -0.5f, 0.0f, 0.043f, 0.719f, 1.0f, -0.499f, 0.0f, 0.04f, 0.724f, 1.0f, -0.497f, 0.0f, 0.038f, 0.73f, 1.0f, -0.495f, 0.0f, 0.035f, 0.735f, 1.0f,
+ -0.493f, 0.0f, 0.032f, 0.741f, 1.0f, -0.491f, 0.0f, 0.029f, 0.748f, 1.0f, -0.489f, 0.0f, 0.026f, 0.754f, 1.0f, -0.488f, -0.0f, 0.024f, 0.76f, 1.0f,
+ -0.486f, -0.0f, 0.022f, 0.767f, 1.0f, -0.485f, -0.0f, 0.019f, 0.773f, 1.0f, -0.483f, -0.0f, 0.017f, 0.779f, 1.0f, -0.482f, -0.0f, 0.015f, 0.785f, 1.0f,
+ -0.48f, -0.0f, 0.013f, 0.79f, 1.0f, -0.478f, -0.0f, 0.01f, 0.795f, 1.0f, -0.476f, -0.0f, 0.008f, 0.8f, 1.0f, -0.474f, -0.0f, 0.006f, 0.804f, 1.0f,
+ -0.472f, -0.0f, 0.004f, 0.808f, 1.0f, -0.47f, -0.0f, 0.002f, 0.811f, 1.0f, -0.468f, -0.0f, -0.0f, 0.814f, 1.0f, -0.466f, -0.0f, -0.002f, 0.816f, 1.0f,
+ -0.464f, -0.0f, -0.004f, 0.818f, 1.0f, -0.461f, -0.0f, -0.006f, 0.82f, 1.0f, -0.459f, -0.0f, -0.008f, 0.822f, 1.0f, -0.456f, -0.0f, -0.01f, 0.823f, 1.0f,
+ -0.454f, -0.0f, -0.012f, 0.825f, 1.0f, -0.451f, -0.0f, -0.014f, 0.826f, 1.0f, -0.448f, -0.0f, -0.016f, 0.827f, 1.0f, -0.445f, -0.0f, -0.018f, 0.828f, 1.0f,
+ -0.442f, -0.0f, -0.02f, 0.829f, 1.0f, -0.439f, -0.0f, -0.022f, 0.829f, 1.0f, -0.436f, -0.0f, -0.024f, 0.83f, 1.0f, -0.433f, -0.0f, -0.026f, 0.83f, 1.0f,
+ -0.43f, -0.0f, -0.027f, 0.83f, 1.0f, -0.426f, -0.0f, -0.029f, 0.83f, 1.0f, -0.423f, 0.0f, -0.031f, 0.83f, 1.0f, -0.42f, 0.0f, -0.032f, 0.83f, 1.0f,
+ -0.417f, 0.0f, -0.033f, 0.831f, 1.0f, -0.414f, 0.0f, -0.034f, 0.831f, 1.0f, -0.411f, 0.0f, -0.035f, 0.831f, 1.0f, -0.408f, 0.0f, -0.037f, 0.831f, 1.0f,
+ -0.405f, 0.0f, -0.038f, 0.831f, 1.0f, -0.402f, 0.0f, -0.039f, 0.831f, 1.0f, -0.399f, 0.0f, -0.039f, 0.831f, 1.0f, -0.396f, 0.0f, -0.04f, 0.832f, 1.0f,
+ -0.393f, 0.0f, -0.041f, 0.832f, 1.0f, -0.389f, 0.0f, -0.042f, 0.832f, 1.0f, -0.386f, 0.0f, -0.043f, 0.832f, 1.0f, -0.383f, 0.0f, -0.044f, 0.832f, 1.0f,
+ -0.379f, 0.0f, -0.044f, 0.832f, 1.0f, -0.376f, 0.0f, -0.045f, 0.832f, 1.0f, -0.372f, 0.0f, -0.045f, 0.832f, 1.0f, -0.369f, 0.0f, -0.046f, 0.832f, 1.0f,
+ -0.366f, 0.0f, -0.047f, 0.832f, 1.0f, -0.362f, 0.0f, -0.047f, 0.832f, 1.0f, -0.359f, 0.0f, -0.047f, 0.831f, 1.0f, -0.355f, 0.0f, -0.048f, 0.831f, 1.0f,
+ -0.352f, 0.0f, -0.048f, 0.83f, 1.0f, -0.348f, 0.0f, -0.048f, 0.83f, 1.0f, -0.345f, 0.0f, -0.049f, 0.829f, 1.0f, -0.341f, 0.0f, -0.049f, 0.828f, 1.0f,
+ -0.338f, 0.0f, -0.049f, 0.827f, 1.0f, -0.334f, 0.0f, -0.049f, 0.826f, 1.0f, -0.331f, 0.0f, -0.049f, 0.823f, 1.0f, -0.327f, 0.0f, -0.049f, 0.82f, 1.0f,
+ -0.323f, 0.0f, -0.048f, 0.816f, 1.0f, -0.32f, 0.0f, -0.048f, 0.811f, 1.0f, -0.316f, 0.0f, -0.048f, 0.804f, 1.0f, -0.313f, 0.0f, -0.048f, 0.797f, 1.0f,
+ -0.309f, 0.0f, -0.047f, 0.79f, 1.0f, -0.306f, 0.0f, -0.047f, 0.782f, 1.0f, -0.302f, 0.0f, -0.046f, 0.774f, 1.0f, -0.299f, 0.0f, -0.045f, 0.767f, 1.0f,
+ -0.295f, 0.0f, -0.044f, 0.76f, 1.0f, -0.292f, 0.0f, -0.044f, 0.753f, 1.0f, -0.288f, 0.0f, -0.043f, 0.748f, 1.0f, -0.285f, 0.0f, -0.042f, 0.742f, 1.0f,
+ -0.282f, 0.0f, -0.041f, 0.738f, 1.0f, -0.278f, 0.0f, -0.04f, 0.734f, 1.0f, -0.275f, 0.0f, -0.039f, 0.73f, 1.0f, -0.272f, 0.0f, -0.037f, 0.726f, 1.0f,
+ -0.269f, 0.0f, -0.036f, 0.723f, 1.0f, -0.266f, 0.0f, -0.035f, 0.72f, 1.0f, -0.263f, 0.0f, -0.034f, 0.717f, 1.0f, -0.26f, 0.0f, -0.032f, 0.713f, 1.0f,
+ -0.257f, 0.0f, -0.031f, 0.71f, 1.0f, -0.255f, 0.0f, -0.029f, 0.706f, 1.0f, -0.252f, 0.0f, -0.028f, 0.702f, 1.0f, -0.249f, 0.0f, -0.026f, 0.698f, 1.0f,
+ -0.247f, 0.0f, -0.025f, 0.693f, 1.0f, -0.244f, 0.0f, -0.023f, 0.688f, 1.0f, -0.242f, 0.0f, -0.021f, 0.684f, 1.0f, -0.239f, 0.0f, -0.02f, 0.679f, 1.0f,
+ -0.237f, 0.0f, -0.018f, 0.675f, 1.0f, -0.234f, 0.0f, -0.016f, 0.671f, 1.0f, -0.232f, 0.0f, -0.014f, 0.667f, 1.0f, -0.23f, 0.0f, -0.013f, 0.663f, 1.0f,
+ -0.228f, 0.0f, -0.011f, 0.66f, 1.0f, -0.225f, 0.0f, -0.009f, 0.657f, 1.0f, -0.223f, 0.0f, -0.007f, 0.654f, 1.0f, -0.221f, 0.0f, -0.005f, 0.651f, 1.0f,
+ -0.219f, 0.0f, -0.003f, 0.649f, 1.0f, -0.217f, 0.0f, -0.001f, 0.645f, 1.0f, -0.215f, 0.0f, 0.002f, 0.642f, 1.0f, -0.213f, 0.0f, 0.004f, 0.639f, 1.0f,
+ -0.211f, 0.0f, 0.006f, 0.635f, 1.0f, -0.209f, 0.0f, 0.008f, 0.631f, 1.0f, -0.207f, 0.0f, 0.011f, 0.627f, 1.0f, -0.206f, 0.0f, 0.013f, 0.623f, 1.0f,
+ -0.204f, 0.0f, 0.016f, 0.619f, 1.0f, -0.202f, 0.0f, 0.018f, 0.615f, 1.0f, -0.2f, 0.0f, 0.021f, 0.61f, 1.0f, -0.199f, 0.0f, 0.023f, 0.606f, 1.0f,
+ -0.197f, 0.0f, 0.026f, 0.602f, 1.0f, -0.195f, 0.0f, 0.029f, 0.598f, 1.0f, -0.194f, 0.0f, 0.032f, 0.595f, 1.0f, -0.192f, 0.0f, 0.034f, 0.592f, 1.0f,
+ -0.191f, 0.0f, 0.037f, 0.589f, 1.0f, -0.19f, 0.0f, 0.04f, 0.587f, 1.0f, -0.188f, 0.0f, 0.043f, 0.585f, 1.0f, -0.187f, 0.0f, 0.046f, 0.584f, 1.0f,
+ -0.186f, 0.0f, 0.05f, 0.583f, 1.0f, -0.185f, 0.0f, 0.053f, 0.582f, 1.0f, -0.183f, 0.0f, 0.056f, 0.581f, 1.0f, -0.182f, 0.0f, 0.059f, 0.581f, 1.0f,
+ -0.181f, 0.0f, 0.062f, 0.581f, 1.0f, -0.18f, 0.0f, 0.066f, 0.581f, 1.0f, -0.179f, 0.0f, 0.069f, 0.58f, 1.0f, -0.178f, 0.0f, 0.072f, 0.58f, 1.0f,
+ -0.177f, 0.0f, 0.076f, 0.58f, 1.0f, -0.177f, 0.0f, 0.079f, 0.58f, 1.0f, -0.176f, 0.0f, 0.083f, 0.58f, 1.0f, -0.175f, 0.0f, 0.086f, 0.58f, 1.0f,
+ -0.174f, 0.0f, 0.09f, 0.58f, 1.0f, -0.174f, 0.0f, 0.093f, 0.58f, 1.0f, -0.173f, 0.0f, 0.097f, 0.58f, 1.0f, -0.172f, 0.0f, 0.1f, 0.58f, 1.0f,
+ -0.172f, 0.0f, 0.104f, 0.58f, 1.0f, -0.171f, 0.0f, 0.108f, 0.579f, 1.0f, -0.171f, 0.0f, 0.111f, 0.579f, 1.0f, -0.17f, 0.0f, 0.115f, 0.578f, 1.0f,
+ -0.17f, 0.0f, 0.119f, 0.578f, 1.0f, -0.17f, 0.0f, 0.122f, 0.577f, 1.0f, -0.169f, 0.0f, 0.126f, 0.577f, 1.0f, -0.169f, 0.0f, 0.13f, 0.576f, 1.0f,
+ -0.169f, 0.0f, 0.134f, 0.576f, 1.0f, -0.169f, 0.0f, 0.137f, 0.575f, 1.0f, -0.169f, 0.0f, 0.141f, 0.575f, 1.0f, -0.169f, 0.0f, 0.145f, 0.574f, 1.0f,
+ -0.169f, 0.0f, 0.149f, 0.572f, 1.0f, -0.169f, 0.0f, 0.153f, 0.571f, 1.0f, -0.169f, 0.0f, 0.157f, 0.569f, 1.0f, -0.169f, 0.0f, 0.16f, 0.566f, 1.0f,
+ -0.169f, 0.0f, 0.164f, 0.562f, 1.0f, -0.17f, 0.0f, 0.168f, 0.558f, 1.0f, -0.17f, 0.0f, 0.172f, 0.553f, 1.0f, -0.17f, 0.0f, 0.176f, 0.547f, 1.0f,
+ -0.171f, 0.0f, 0.18f, 0.539f, 1.0f, -0.171f, 0.0f, 0.183f, 0.531f, 1.0f, -0.172f, 0.0f, 0.187f, 0.522f, 1.0f, -0.172f, 0.0f, 0.191f, 0.513f, 1.0f,
+ -0.173f, 0.0f, 0.194f, 0.503f, 1.0f, -0.173f, 0.0f, 0.198f, 0.493f, 1.0f, -0.174f, 0.0f, 0.202f, 0.483f, 1.0f, -0.175f, 0.0f, 0.205f, 0.473f, 1.0f,
+ -0.176f, 0.0f, 0.209f, 0.464f, 1.0f, -0.177f, 0.0f, 0.212f, 0.455f, 1.0f, -0.178f, 0.0f, 0.215f, 0.446f, 1.0f, -0.178f, 0.0f, 0.219f, 0.438f, 1.0f,
+ -0.179f, 0.0f, 0.222f, 0.428f, 1.0f, -0.18f, 0.0f, 0.226f, 0.418f, 1.0f, -0.182f, 0.0f, 0.229f, 0.407f, 1.0f, -0.183f, 0.0f, 0.232f, 0.394f, 1.0f,
+ -0.184f, 0.0f, 0.236f, 0.38f, 1.0f, -0.185f, 0.0f, 0.239f, 0.364f, 1.0f, -0.186f, 0.0f, 0.242f, 0.348f, 1.0f, -0.187f, 0.0f, 0.245f, 0.33f, 1.0f,
+ -0.188f, 0.0f, 0.249f, 0.311f, 1.0f, -0.19f, 0.0f, 0.252f, 0.293f, 1.0f, -0.191f, 0.0f, 0.255f, 0.275f, 1.0f, -0.192f, 0.0f, 0.258f, 0.258f, 1.0f,
+ -0.194f, 0.0f, 0.261f, 0.242f, 1.0f, -0.195f, 0.0f, 0.264f, 0.228f, 1.0f, -0.196f, 0.0f, 0.267f, 0.214f, 1.0f, -0.198f, 0.0f, 0.27f, 0.202f, 1.0f,
+ -0.199f, 0.0f, 0.273f, 0.191f, 1.0f, -0.201f, 0.0f, 0.276f, 0.181f, 1.0f, -0.202f, 0.0f, 0.279f, 0.171f, 1.0f, -0.204f, 0.0f, 0.282f, 0.162f, 1.0f,
+ -0.205f, 0.0f, 0.285f, 0.152f, 1.0f, -0.206f, 0.0f, 0.287f, 0.143f, 1.0f, -0.208f, 0.0f, 0.29f, 0.134f, 1.0f, -0.21f, 0.0f, 0.293f, 0.126f, 1.0f,
+ -0.211f, 0.0f, 0.295f, 0.117f, 1.0f, -0.213f, 0.0f, 0.298f, 0.109f, 1.0f, -0.214f, 0.0f, 0.301f, 0.101f, 1.0f, -0.216f, 0.0f, 0.303f, 0.094f, 1.0f,
+ -0.217f, 0.0f, 0.306f, 0.087f, 1.0f, -0.219f, 0.0f, 0.308f, 0.081f, 1.0f, -0.221f, 0.0f, 0.311f, 0.076f, 1.0f, -0.223f, 0.0f, 0.313f, 0.071f, 1.0f,
+ -0.224f, 0.0f, 0.316f, 0.067f, 1.0f, -0.226f, 0.0f, 0.318f, 0.065f, 1.0f, -0.228f, 0.0f, 0.321f, 0.062f, 1.0f, -0.23f, 0.0f, 0.323f, 0.061f, 1.0f,
+ -0.232f, 0.0f, 0.326f, 0.06f, 1.0f, -0.233f, 0.0f, 0.328f, 0.06f, 1.0f, -0.235f, 0.0f, 0.331f, 0.061f, 1.0f, -0.237f, 0.0f, 0.334f, 0.061f, 1.0f,
+ -0.239f, 0.0f, 0.336f, 0.062f, 1.0f, -0.241f, 0.0f, 0.339f, 0.063f, 1.0f, -0.243f, 0.0f, 0.341f, 0.064f, 1.0f, -0.245f, 0.0f, 0.344f, 0.065f, 1.0f,
+ -0.248f, 0.0f, 0.346f, 0.065f, 1.0f, -0.25f, 0.0f, 0.349f, 0.065f, 1.0f, -0.252f, 0.0f, 0.351f, 0.064f, 1.0f, -0.254f, 0.0f, 0.354f, 0.062f, 1.0f,
+ -0.256f, 0.0f, 0.356f, 0.06f, 1.0f, -0.258f, 0.0f, 0.359f, 0.058f, 1.0f, -0.261f, 0.0f, 0.361f, 0.055f, 1.0f, -0.263f, 0.0f, 0.364f, 0.051f, 1.0f,
+ -0.265f, 0.0f, 0.366f, 0.046f, 1.0f, -0.267f, 0.0f, 0.368f, 0.04f, 1.0f, -0.269f, 0.0f, 0.37f, 0.034f, 1.0f, -0.272f, 0.0f, 0.373f, 0.027f, 1.0f,
+ -0.274f, 0.0f, 0.375f, 0.019f, 1.0f, -0.276f, 0.0f, 0.377f, 0.012f, 1.0f, -0.278f, 0.0f, 0.379f, 0.007f, 1.0f, -0.28f, 0.0f, 0.381f, 0.003f, 1.0f,
+ -0.282f, 0.0f, 0.383f, 0.001f, 1.0f, -0.284f, 0.0f, 0.385f, 0.0f, 1.0f, -0.286f, 0.0f, 0.387f, 0.0f, 1.0f, -0.287f, 0.0f, 0.388f, 0.0f, 1.0f,
+ -0.289f, 0.0f, 0.39f, 0.0f, 1.0f,
+};
+
+static const float data22[309 * GP_PRIM_DATABUF_SIZE] = {
+ 0.294f, 0.0f, 0.372f, 0.0f, 1.0f, 0.291f, 0.0f, 0.37f, 0.001f, 1.0f, 0.289f, 0.0f, 0.368f, 0.002f, 1.0f, 0.286f, 0.0f, 0.366f, 0.003f, 1.0f,
+ 0.284f, 0.0f, 0.364f, 0.006f, 1.0f, 0.282f, 0.0f, 0.362f, 0.01f, 1.0f, 0.279f, 0.0f, 0.36f, 0.015f, 1.0f, 0.277f, 0.0f, 0.358f, 0.022f, 1.0f,
+ 0.274f, 0.0f, 0.356f, 0.03f, 1.0f, 0.272f, 0.0f, 0.353f, 0.04f, 1.0f, 0.269f, 0.0f, 0.351f, 0.051f, 1.0f, 0.267f, 0.0f, 0.349f, 0.062f, 1.0f,
+ 0.265f, 0.0f, 0.347f, 0.074f, 1.0f, 0.262f, 0.0f, 0.344f, 0.086f, 1.0f, 0.26f, 0.0f, 0.342f, 0.097f, 1.0f, 0.258f, 0.0f, 0.34f, 0.108f, 1.0f,
+ 0.256f, 0.0f, 0.337f, 0.119f, 1.0f, 0.253f, 0.0f, 0.335f, 0.128f, 1.0f, 0.251f, 0.0f, 0.333f, 0.137f, 1.0f, 0.249f, 0.0f, 0.33f, 0.145f, 1.0f,
+ 0.247f, 0.0f, 0.328f, 0.153f, 1.0f, 0.246f, 0.0f, 0.325f, 0.161f, 1.0f, 0.244f, 0.0f, 0.323f, 0.168f, 1.0f, 0.242f, 0.0f, 0.321f, 0.176f, 1.0f,
+ 0.24f, 0.0f, 0.318f, 0.183f, 1.0f, 0.239f, 0.0f, 0.316f, 0.191f, 1.0f, 0.237f, 0.0f, 0.314f, 0.198f, 1.0f, 0.235f, 0.0f, 0.311f, 0.206f, 1.0f,
+ 0.233f, 0.0f, 0.309f, 0.214f, 1.0f, 0.231f, 0.0f, 0.306f, 0.223f, 1.0f, 0.23f, 0.0f, 0.304f, 0.231f, 1.0f, 0.228f, 0.0f, 0.301f, 0.24f, 1.0f,
+ 0.226f, 0.0f, 0.299f, 0.248f, 1.0f, 0.224f, 0.0f, 0.296f, 0.256f, 1.0f, 0.223f, 0.0f, 0.294f, 0.264f, 1.0f, 0.221f, 0.0f, 0.291f, 0.272f, 1.0f,
+ 0.219f, 0.0f, 0.288f, 0.28f, 1.0f, 0.218f, 0.0f, 0.286f, 0.287f, 1.0f, 0.216f, 0.0f, 0.283f, 0.294f, 1.0f, 0.214f, 0.0f, 0.281f, 0.301f, 1.0f,
+ 0.213f, 0.0f, 0.278f, 0.307f, 1.0f, 0.211f, 0.0f, 0.275f, 0.314f, 1.0f, 0.21f, 0.0f, 0.273f, 0.32f, 1.0f, 0.208f, 0.0f, 0.27f, 0.327f, 1.0f,
+ 0.206f, 0.0f, 0.267f, 0.333f, 1.0f, 0.205f, 0.0f, 0.265f, 0.339f, 1.0f, 0.204f, 0.0f, 0.262f, 0.345f, 1.0f, 0.202f, 0.0f, 0.259f, 0.351f, 1.0f,
+ 0.201f, 0.0f, 0.256f, 0.357f, 1.0f, 0.199f, 0.0f, 0.253f, 0.362f, 1.0f, 0.198f, 0.0f, 0.25f, 0.368f, 1.0f, 0.197f, 0.0f, 0.247f, 0.373f, 1.0f,
+ 0.195f, 0.0f, 0.244f, 0.379f, 1.0f, 0.194f, 0.0f, 0.241f, 0.383f, 1.0f, 0.193f, 0.0f, 0.238f, 0.388f, 1.0f, 0.192f, 0.0f, 0.235f, 0.392f, 1.0f,
+ 0.191f, 0.0f, 0.232f, 0.396f, 1.0f, 0.19f, 0.0f, 0.229f, 0.399f, 1.0f, 0.189f, 0.0f, 0.226f, 0.402f, 1.0f, 0.188f, 0.0f, 0.222f, 0.405f, 1.0f,
+ 0.187f, 0.0f, 0.219f, 0.407f, 1.0f, 0.186f, 0.0f, 0.216f, 0.409f, 1.0f, 0.185f, 0.0f, 0.213f, 0.411f, 1.0f, 0.184f, 0.0f, 0.209f, 0.412f, 1.0f,
+ 0.183f, 0.0f, 0.206f, 0.413f, 1.0f, 0.183f, 0.0f, 0.203f, 0.414f, 1.0f, 0.182f, 0.0f, 0.199f, 0.415f, 1.0f, 0.181f, 0.0f, 0.196f, 0.416f, 1.0f,
+ 0.181f, 0.0f, 0.193f, 0.417f, 1.0f, 0.18f, 0.0f, 0.189f, 0.417f, 1.0f, 0.18f, 0.0f, 0.186f, 0.418f, 1.0f, 0.179f, 0.0f, 0.182f, 0.419f, 1.0f,
+ 0.179f, 0.0f, 0.179f, 0.421f, 1.0f, 0.179f, 0.0f, 0.176f, 0.422f, 1.0f, 0.178f, 0.0f, 0.172f, 0.423f, 1.0f, 0.178f, 0.0f, 0.169f, 0.425f, 1.0f,
+ 0.178f, 0.0f, 0.165f, 0.427f, 1.0f, 0.178f, 0.0f, 0.162f, 0.429f, 1.0f, 0.178f, 0.0f, 0.158f, 0.431f, 1.0f, 0.178f, 0.0f, 0.155f, 0.434f, 1.0f,
+ 0.178f, 0.0f, 0.152f, 0.436f, 1.0f, 0.178f, 0.0f, 0.148f, 0.439f, 1.0f, 0.178f, 0.0f, 0.145f, 0.442f, 1.0f, 0.178f, 0.0f, 0.141f, 0.446f, 1.0f,
+ 0.178f, 0.0f, 0.138f, 0.449f, 1.0f, 0.178f, 0.0f, 0.134f, 0.453f, 1.0f, 0.178f, 0.0f, 0.131f, 0.458f, 1.0f, 0.179f, 0.0f, 0.127f, 0.462f, 1.0f,
+ 0.179f, 0.0f, 0.124f, 0.467f, 1.0f, 0.179f, 0.0f, 0.12f, 0.472f, 1.0f, 0.18f, 0.0f, 0.117f, 0.478f, 1.0f, 0.18f, 0.0f, 0.113f, 0.483f, 1.0f,
+ 0.181f, 0.0f, 0.11f, 0.489f, 1.0f, 0.182f, 0.0f, 0.106f, 0.494f, 1.0f, 0.182f, 0.0f, 0.103f, 0.5f, 1.0f, 0.183f, 0.0f, 0.099f, 0.505f, 1.0f,
+ 0.184f, 0.0f, 0.096f, 0.511f, 1.0f, 0.185f, 0.0f, 0.092f, 0.516f, 1.0f, 0.185f, 0.0f, 0.089f, 0.521f, 1.0f, 0.186f, 0.0f, 0.086f, 0.525f, 1.0f,
+ 0.187f, 0.0f, 0.082f, 0.53f, 1.0f, 0.188f, 0.0f, 0.079f, 0.534f, 1.0f, 0.189f, 0.0f, 0.076f, 0.537f, 1.0f, 0.191f, 0.0f, 0.073f, 0.541f, 1.0f,
+ 0.192f, 0.0f, 0.069f, 0.544f, 1.0f, 0.193f, 0.0f, 0.066f, 0.547f, 1.0f, 0.194f, 0.0f, 0.063f, 0.55f, 1.0f, 0.196f, 0.0f, 0.061f, 0.553f, 1.0f,
+ 0.197f, 0.0f, 0.058f, 0.556f, 1.0f, 0.198f, 0.0f, 0.055f, 0.559f, 1.0f, 0.2f, 0.0f, 0.052f, 0.562f, 1.0f, 0.201f, 0.0f, 0.049f, 0.564f, 1.0f,
+ 0.203f, 0.0f, 0.047f, 0.566f, 1.0f, 0.205f, 0.0f, 0.044f, 0.569f, 1.0f, 0.206f, 0.0f, 0.042f, 0.571f, 1.0f, 0.208f, 0.0f, 0.039f, 0.573f, 1.0f,
+ 0.21f, 0.0f, 0.037f, 0.575f, 1.0f, 0.212f, 0.0f, 0.035f, 0.576f, 1.0f, 0.214f, 0.0f, 0.032f, 0.578f, 1.0f, 0.215f, 0.0f, 0.03f, 0.579f, 1.0f,
+ 0.217f, 0.0f, 0.028f, 0.581f, 1.0f, 0.22f, 0.0f, 0.025f, 0.582f, 1.0f, 0.222f, 0.0f, 0.023f, 0.583f, 1.0f, 0.224f, 0.0f, 0.021f, 0.585f, 1.0f,
+ 0.226f, 0.0f, 0.019f, 0.587f, 1.0f, 0.228f, 0.0f, 0.016f, 0.589f, 1.0f, 0.231f, 0.0f, 0.014f, 0.592f, 1.0f, 0.233f, 0.0f, 0.012f, 0.596f, 1.0f,
+ 0.236f, 0.0f, 0.01f, 0.599f, 1.0f, 0.238f, 0.0f, 0.008f, 0.604f, 1.0f, 0.241f, 0.0f, 0.006f, 0.608f, 1.0f, 0.243f, 0.0f, 0.004f, 0.612f, 1.0f,
+ 0.246f, 0.0f, 0.002f, 0.615f, 1.0f, 0.249f, 0.0f, 0.0f, 0.619f, 1.0f, 0.251f, 0.0f, -0.002f, 0.622f, 1.0f, 0.254f, 0.0f, -0.003f, 0.624f, 1.0f,
+ 0.257f, 0.0f, -0.005f, 0.626f, 1.0f, 0.26f, 0.0f, -0.007f, 0.628f, 1.0f, 0.263f, 0.0f, -0.008f, 0.63f, 1.0f, 0.266f, 0.0f, -0.01f, 0.632f, 1.0f,
+ 0.269f, 0.0f, -0.011f, 0.634f, 1.0f, 0.272f, 0.0f, -0.013f, 0.636f, 1.0f, 0.275f, 0.0f, -0.014f, 0.638f, 1.0f, 0.278f, 0.0f, -0.015f, 0.64f, 1.0f,
+ 0.281f, 0.0f, -0.017f, 0.642f, 1.0f, 0.284f, 0.0f, -0.018f, 0.644f, 1.0f, 0.288f, 0.0f, -0.019f, 0.647f, 1.0f, 0.291f, 0.0f, -0.02f, 0.649f, 1.0f,
+ 0.294f, 0.0f, -0.021f, 0.651f, 1.0f, 0.297f, 0.0f, -0.022f, 0.653f, 1.0f, 0.301f, 0.0f, -0.023f, 0.656f, 1.0f, 0.304f, 0.0f, -0.024f, 0.658f, 1.0f,
+ 0.307f, 0.0f, -0.025f, 0.659f, 1.0f, 0.31f, 0.0f, -0.026f, 0.661f, 1.0f, 0.314f, 0.0f, -0.027f, 0.662f, 1.0f, 0.317f, 0.0f, -0.027f, 0.664f, 1.0f,
+ 0.32f, 0.0f, -0.028f, 0.665f, 1.0f, 0.324f, 0.0f, -0.028f, 0.665f, 1.0f, 0.327f, 0.0f, -0.029f, 0.666f, 1.0f, 0.33f, 0.0f, -0.029f, 0.666f, 1.0f,
+ 0.334f, 0.0f, -0.029f, 0.667f, 1.0f, 0.337f, 0.0f, -0.03f, 0.667f, 1.0f, 0.341f, 0.0f, -0.03f, 0.668f, 1.0f, 0.344f, 0.0f, -0.03f, 0.668f, 1.0f,
+ 0.348f, 0.0f, -0.03f, 0.668f, 1.0f, 0.351f, 0.0f, -0.03f, 0.668f, 1.0f, 0.354f, 0.0f, -0.03f, 0.668f, 1.0f, 0.358f, 0.0f, -0.029f, 0.668f, 1.0f,
+ 0.361f, 0.0f, -0.029f, 0.668f, 1.0f, 0.365f, 0.0f, -0.029f, 0.668f, 1.0f, 0.368f, 0.0f, -0.028f, 0.668f, 1.0f, 0.372f, 0.0f, -0.028f, 0.668f, 1.0f,
+ 0.375f, 0.0f, -0.027f, 0.668f, 1.0f, 0.378f, 0.0f, -0.027f, 0.668f, 1.0f, 0.382f, 0.0f, -0.026f, 0.667f, 1.0f, 0.385f, 0.0f, -0.025f, 0.667f, 1.0f,
+ 0.388f, 0.0f, -0.025f, 0.666f, 1.0f, 0.392f, 0.0f, -0.024f, 0.666f, 1.0f, 0.395f, 0.0f, -0.023f, 0.665f, 1.0f, 0.398f, 0.0f, -0.022f, 0.664f, 1.0f,
+ 0.401f, 0.0f, -0.021f, 0.664f, 1.0f, 0.405f, 0.0f, -0.02f, 0.663f, 1.0f, 0.408f, 0.0f, -0.019f, 0.663f, 1.0f, 0.411f, 0.0f, -0.018f, 0.662f, 1.0f,
+ 0.414f, 0.0f, -0.017f, 0.662f, 1.0f, 0.417f, 0.0f, -0.016f, 0.662f, 1.0f, 0.42f, 0.0f, -0.015f, 0.662f, 1.0f, 0.423f, 0.0f, -0.014f, 0.661f, 1.0f,
+ 0.426f, 0.0f, -0.012f, 0.661f, 1.0f, 0.429f, 0.0f, -0.011f, 0.661f, 1.0f, 0.432f, 0.0f, -0.01f, 0.661f, 1.0f, 0.434f, 0.0f, -0.009f, 0.66f, 1.0f,
+ 0.437f, 0.0f, -0.007f, 0.66f, 1.0f, 0.44f, 0.0f, -0.006f, 0.659f, 1.0f, 0.442f, 0.0f, -0.005f, 0.659f, 1.0f, 0.445f, 0.0f, -0.003f, 0.658f, 1.0f,
+ 0.448f, 0.0f, -0.002f, 0.658f, 1.0f, 0.45f, 0.0f, -0.001f, 0.657f, 1.0f, 0.452f, 0.0f, 0.001f, 0.656f, 1.0f, 0.455f, 0.0f, 0.002f, 0.655f, 1.0f,
+ 0.457f, 0.0f, 0.004f, 0.654f, 1.0f, 0.459f, 0.0f, 0.005f, 0.653f, 1.0f, 0.462f, 0.0f, 0.007f, 0.652f, 1.0f, 0.464f, 0.0f, 0.009f, 0.651f, 1.0f,
+ 0.466f, 0.0f, 0.01f, 0.65f, 1.0f, 0.468f, 0.0f, 0.012f, 0.65f, 1.0f, 0.47f, 0.0f, 0.014f, 0.649f, 1.0f, 0.472f, 0.0f, 0.016f, 0.648f, 1.0f,
+ 0.474f, 0.0f, 0.018f, 0.647f, 1.0f, 0.476f, 0.0f, 0.019f, 0.646f, 1.0f, 0.478f, 0.0f, 0.021f, 0.645f, 1.0f, 0.479f, 0.0f, 0.023f, 0.644f, 1.0f,
+ 0.481f, 0.0f, 0.025f, 0.643f, 1.0f, 0.483f, 0.0f, 0.027f, 0.642f, 1.0f, 0.485f, 0.0f, 0.03f, 0.642f, 1.0f, 0.486f, 0.0f, 0.032f, 0.641f, 1.0f,
+ 0.488f, 0.0f, 0.034f, 0.64f, 1.0f, 0.49f, 0.0f, 0.036f, 0.639f, 1.0f, 0.491f, 0.0f, 0.038f, 0.638f, 1.0f, 0.493f, 0.0f, 0.041f, 0.637f, 1.0f,
+ 0.494f, 0.0f, 0.043f, 0.636f, 1.0f, 0.496f, 0.0f, 0.045f, 0.635f, 1.0f, 0.497f, 0.0f, 0.048f, 0.635f, 1.0f, 0.499f, 0.0f, 0.05f, 0.634f, 1.0f,
+ 0.5f, 0.0f, 0.053f, 0.633f, 1.0f, 0.502f, 0.0f, 0.055f, 0.632f, 1.0f, 0.503f, 0.0f, 0.058f, 0.631f, 1.0f, 0.505f, 0.0f, 0.06f, 0.63f, 1.0f,
+ 0.506f, 0.0f, 0.063f, 0.63f, 1.0f, 0.507f, 0.0f, 0.066f, 0.629f, 1.0f, 0.509f, 0.0f, 0.068f, 0.628f, 1.0f, 0.51f, 0.0f, 0.071f, 0.628f, 1.0f,
+ 0.511f, 0.0f, 0.074f, 0.627f, 1.0f, 0.513f, 0.0f, 0.077f, 0.626f, 1.0f, 0.514f, 0.0f, 0.079f, 0.625f, 1.0f, 0.515f, 0.0f, 0.082f, 0.625f, 1.0f,
+ 0.516f, 0.0f, 0.085f, 0.624f, 1.0f, 0.518f, 0.0f, 0.088f, 0.623f, 1.0f, 0.519f, 0.0f, 0.091f, 0.622f, 1.0f, 0.52f, 0.0f, 0.094f, 0.62f, 1.0f,
+ 0.521f, 0.0f, 0.098f, 0.619f, 1.0f, 0.522f, 0.0f, 0.101f, 0.617f, 1.0f, 0.523f, 0.0f, 0.104f, 0.615f, 1.0f, 0.524f, 0.0f, 0.107f, 0.613f, 1.0f,
+ 0.525f, 0.0f, 0.111f, 0.611f, 1.0f, 0.526f, 0.0f, 0.114f, 0.609f, 1.0f, 0.527f, 0.0f, 0.118f, 0.607f, 1.0f, 0.527f, 0.0f, 0.121f, 0.605f, 1.0f,
+ 0.528f, 0.0f, 0.124f, 0.603f, 1.0f, 0.529f, 0.0f, 0.128f, 0.602f, 1.0f, 0.529f, 0.0f, 0.132f, 0.6f, 1.0f, 0.53f, 0.0f, 0.135f, 0.599f, 1.0f,
+ 0.531f, 0.0f, 0.139f, 0.598f, 1.0f, 0.531f, 0.0f, 0.142f, 0.598f, 1.0f, 0.531f, 0.0f, 0.146f, 0.597f, 1.0f, 0.532f, 0.0f, 0.15f, 0.596f, 1.0f,
+ 0.532f, 0.0f, 0.154f, 0.596f, 1.0f, 0.532f, 0.0f, 0.157f, 0.595f, 1.0f, 0.532f, 0.0f, 0.161f, 0.595f, 1.0f, 0.532f, 0.0f, 0.165f, 0.594f, 1.0f,
+ 0.532f, 0.0f, 0.169f, 0.593f, 1.0f, 0.532f, 0.0f, 0.173f, 0.592f, 1.0f, 0.532f, 0.0f, 0.177f, 0.591f, 1.0f, 0.532f, 0.0f, 0.181f, 0.59f, 1.0f,
+ 0.531f, 0.0f, 0.185f, 0.589f, 1.0f, 0.531f, 0.0f, 0.189f, 0.588f, 1.0f, 0.53f, 0.0f, 0.194f, 0.587f, 1.0f, 0.529f, 0.0f, 0.198f, 0.586f, 1.0f,
+ 0.528f, 0.0f, 0.202f, 0.585f, 1.0f, 0.527f, 0.0f, 0.207f, 0.584f, 1.0f, 0.526f, 0.0f, 0.211f, 0.584f, 1.0f, 0.525f, 0.0f, 0.215f, 0.583f, 1.0f,
+ 0.523f, 0.0f, 0.22f, 0.583f, 1.0f, 0.522f, 0.0f, 0.224f, 0.583f, 1.0f, 0.52f, 0.0f, 0.229f, 0.582f, 1.0f, 0.518f, 0.0f, 0.234f, 0.582f, 1.0f,
+ 0.515f, 0.0f, 0.238f, 0.582f, 1.0f, 0.513f, 0.0f, 0.243f, 0.581f, 1.0f, 0.51f, 0.0f, 0.247f, 0.58f, 1.0f, 0.508f, 0.0f, 0.252f, 0.579f, 1.0f,
+ 0.505f, 0.0f, 0.257f, 0.578f, 1.0f, 0.502f, 0.0f, 0.261f, 0.576f, 1.0f, 0.499f, 0.0f, 0.266f, 0.573f, 1.0f, 0.496f, 0.0f, 0.27f, 0.57f, 1.0f,
+ 0.492f, 0.0f, 0.275f, 0.566f, 1.0f, 0.489f, 0.0f, 0.279f, 0.561f, 1.0f, 0.485f, 0.0f, 0.284f, 0.555f, 1.0f, 0.481f, 0.0f, 0.288f, 0.548f, 1.0f,
+ 0.478f, 0.0f, 0.293f, 0.54f, 1.0f, 0.473f, 0.0f, 0.297f, 0.531f, 1.0f, 0.469f, 0.0f, 0.301f, 0.521f, 1.0f, 0.465f, 0.0f, 0.305f, 0.509f, 1.0f,
+ 0.461f, 0.0f, 0.309f, 0.496f, 1.0f, 0.456f, 0.0f, 0.313f, 0.481f, 1.0f, 0.452f, 0.0f, 0.317f, 0.464f, 1.0f, 0.448f, 0.0f, 0.321f, 0.445f, 1.0f,
+ 0.443f, 0.0f, 0.324f, 0.424f, 1.0f, 0.438f, 0.0f, 0.328f, 0.401f, 1.0f, 0.434f, 0.0f, 0.331f, 0.374f, 1.0f, 0.429f, 0.0f, 0.334f, 0.346f, 1.0f,
+ 0.425f, 0.0f, 0.337f, 0.314f, 1.0f, 0.421f, 0.0f, 0.34f, 0.281f, 1.0f, 0.416f, 0.0f, 0.343f, 0.245f, 1.0f, 0.412f, 0.0f, 0.346f, 0.208f, 1.0f,
+ 0.408f, 0.0f, 0.349f, 0.169f, 1.0f, 0.404f, 0.0f, 0.351f, 0.13f, 1.0f, 0.401f, 0.0f, 0.354f, 0.089f, 1.0f, 0.398f, 0.0f, 0.356f, 0.054f, 1.0f,
+ 0.394f, 0.0f, 0.359f, 0.0f, 1.0f,
+};
+
+static const float data23[209 * GP_PRIM_DATABUF_SIZE] = {
+ -0.751f, 0.0f, 0.173f, 0.0f, 1.0f, -0.751f, 0.0f, 0.168f, 0.0f, 1.0f, -0.75f, 0.0f, 0.164f, 0.0f, 1.0f, -0.75f, 0.0f, 0.16f, 0.0f, 1.0f,
+ -0.75f, 0.0f, 0.156f, 0.0f, 1.0f, -0.749f, 0.0f, 0.152f, 0.0f, 1.0f, -0.749f, 0.0f, 0.148f, 0.0f, 1.0f, -0.748f, 0.0f, 0.144f, 0.0f, 1.0f,
+ -0.747f, 0.0f, 0.14f, 0.001f, 1.0f, -0.747f, 0.0f, 0.137f, 0.002f, 1.0f, -0.746f, 0.0f, 0.133f, 0.005f, 1.0f, -0.745f, 0.0f, 0.129f, 0.008f, 1.0f,
+ -0.745f, 0.0f, 0.125f, 0.013f, 1.0f, -0.744f, 0.0f, 0.122f, 0.02f, 1.0f, -0.743f, 0.0f, 0.118f, 0.028f, 1.0f, -0.742f, 0.0f, 0.115f, 0.038f, 1.0f,
+ -0.741f, 0.0f, 0.111f, 0.049f, 1.0f, -0.74f, 0.0f, 0.108f, 0.061f, 1.0f, -0.739f, 0.0f, 0.105f, 0.073f, 1.0f, -0.738f, 0.0f, 0.101f, 0.085f, 1.0f,
+ -0.736f, 0.0f, 0.098f, 0.097f, 1.0f, -0.735f, 0.0f, 0.095f, 0.109f, 1.0f, -0.734f, 0.0f, 0.091f, 0.119f, 1.0f, -0.732f, 0.0f, 0.088f, 0.129f, 1.0f,
+ -0.731f, 0.0f, 0.085f, 0.138f, 1.0f, -0.729f, 0.0f, 0.082f, 0.146f, 1.0f, -0.728f, 0.0f, 0.079f, 0.153f, 1.0f, -0.726f, 0.0f, 0.076f, 0.158f, 1.0f,
+ -0.725f, 0.0f, 0.073f, 0.163f, 1.0f, -0.723f, 0.0f, 0.07f, 0.167f, 1.0f, -0.722f, 0.0f, 0.067f, 0.17f, 1.0f, -0.72f, 0.0f, 0.065f, 0.173f, 1.0f,
+ -0.718f, 0.0f, 0.062f, 0.174f, 1.0f, -0.717f, 0.0f, 0.059f, 0.175f, 1.0f, -0.715f, 0.0f, 0.057f, 0.176f, 1.0f, -0.714f, 0.0f, 0.054f, 0.176f, 1.0f,
+ -0.712f, 0.0f, 0.051f, 0.176f, 1.0f, -0.71f, 0.0f, 0.049f, 0.176f, 1.0f, -0.709f, 0.0f, 0.046f, 0.176f, 1.0f, -0.707f, 0.0f, 0.043f, 0.176f, 1.0f,
+ -0.705f, 0.0f, 0.041f, 0.176f, 1.0f, -0.703f, 0.0f, 0.038f, 0.176f, 1.0f, -0.701f, 0.0f, 0.035f, 0.176f, 1.0f, -0.7f, 0.0f, 0.033f, 0.177f, 1.0f,
+ -0.698f, 0.0f, 0.03f, 0.177f, 1.0f, -0.696f, 0.0f, 0.027f, 0.178f, 1.0f, -0.694f, 0.0f, 0.024f, 0.179f, 1.0f, -0.692f, 0.0f, 0.022f, 0.18f, 1.0f,
+ -0.69f, 0.0f, 0.019f, 0.181f, 1.0f, -0.688f, 0.0f, 0.016f, 0.182f, 1.0f, -0.685f, 0.0f, 0.013f, 0.184f, 1.0f, -0.683f, 0.0f, 0.01f, 0.187f, 1.0f,
+ -0.681f, 0.0f, 0.007f, 0.19f, 1.0f, -0.679f, 0.0f, 0.004f, 0.194f, 1.0f, -0.677f, 0.0f, 0.001f, 0.198f, 1.0f, -0.675f, 0.0f, -0.002f, 0.203f, 1.0f,
+ -0.673f, 0.0f, -0.005f, 0.209f, 1.0f, -0.67f, 0.0f, -0.008f, 0.215f, 1.0f, -0.668f, 0.0f, -0.011f, 0.222f, 1.0f, -0.666f, 0.0f, -0.014f, 0.229f, 1.0f,
+ -0.664f, 0.0f, -0.017f, 0.237f, 1.0f, -0.661f, 0.0f, -0.02f, 0.246f, 1.0f, -0.659f, 0.0f, -0.023f, 0.255f, 1.0f, -0.657f, 0.0f, -0.025f, 0.264f, 1.0f,
+ -0.654f, 0.0f, -0.028f, 0.275f, 1.0f, -0.652f, 0.0f, -0.031f, 0.285f, 1.0f, -0.65f, 0.0f, -0.034f, 0.297f, 1.0f, -0.647f, 0.0f, -0.037f, 0.309f, 1.0f,
+ -0.644f, 0.0f, -0.04f, 0.322f, 1.0f, -0.642f, 0.0f, -0.043f, 0.335f, 1.0f, -0.639f, 0.0f, -0.046f, 0.348f, 1.0f, -0.636f, 0.0f, -0.049f, 0.361f, 1.0f,
+ -0.633f, 0.0f, -0.052f, 0.374f, 1.0f, -0.63f, 0.0f, -0.055f, 0.386f, 1.0f, -0.627f, 0.0f, -0.058f, 0.397f, 1.0f, -0.624f, 0.0f, -0.061f, 0.408f, 1.0f,
+ -0.62f, 0.0f, -0.064f, 0.418f, 1.0f, -0.617f, 0.0f, -0.067f, 0.427f, 1.0f, -0.614f, 0.0f, -0.07f, 0.435f, 1.0f, -0.611f, 0.0f, -0.073f, 0.443f, 1.0f,
+ -0.607f, 0.0f, -0.075f, 0.451f, 1.0f, -0.604f, 0.0f, -0.078f, 0.458f, 1.0f, -0.6f, 0.0f, -0.081f, 0.465f, 1.0f, -0.597f, 0.0f, -0.084f, 0.472f, 1.0f,
+ -0.593f, 0.0f, -0.086f, 0.479f, 1.0f, -0.59f, 0.0f, -0.089f, 0.486f, 1.0f, -0.586f, 0.0f, -0.092f, 0.492f, 1.0f, -0.583f, 0.0f, -0.094f, 0.499f, 1.0f,
+ -0.579f, 0.0f, -0.097f, 0.505f, 1.0f, -0.575f, 0.0f, -0.099f, 0.512f, 1.0f, -0.571f, 0.0f, -0.102f, 0.518f, 1.0f, -0.567f, 0.0f, -0.105f, 0.524f, 1.0f,
+ -0.563f, 0.0f, -0.107f, 0.53f, 1.0f, -0.559f, 0.0f, -0.11f, 0.536f, 1.0f, -0.555f, 0.0f, -0.112f, 0.541f, 1.0f, -0.551f, 0.0f, -0.115f, 0.546f, 1.0f,
+ -0.546f, 0.0f, -0.117f, 0.551f, 1.0f, -0.542f, 0.0f, -0.12f, 0.555f, 1.0f, -0.538f, 0.0f, -0.122f, 0.559f, 1.0f, -0.533f, 0.0f, -0.125f, 0.562f, 1.0f,
+ -0.529f, 0.0f, -0.127f, 0.565f, 1.0f, -0.525f, 0.0f, -0.129f, 0.568f, 1.0f, -0.52f, 0.0f, -0.132f, 0.57f, 1.0f, -0.516f, 0.0f, -0.134f, 0.572f, 1.0f,
+ -0.512f, 0.0f, -0.137f, 0.574f, 1.0f, -0.508f, 0.0f, -0.139f, 0.576f, 1.0f, -0.503f, 0.0f, -0.141f, 0.577f, 1.0f, -0.499f, 0.0f, -0.144f, 0.578f, 1.0f,
+ -0.495f, 0.0f, -0.146f, 0.579f, 1.0f, -0.491f, 0.0f, -0.148f, 0.579f, 1.0f, -0.487f, 0.0f, -0.151f, 0.578f, 1.0f, -0.483f, 0.0f, -0.153f, 0.577f, 1.0f,
+ -0.479f, 0.0f, -0.155f, 0.574f, 1.0f, -0.475f, 0.0f, -0.158f, 0.571f, 1.0f, -0.471f, 0.0f, -0.16f, 0.567f, 1.0f, -0.467f, 0.0f, -0.162f, 0.561f, 1.0f,
+ -0.463f, 0.0f, -0.165f, 0.555f, 1.0f, -0.459f, 0.0f, -0.167f, 0.548f, 1.0f, -0.456f, 0.0f, -0.169f, 0.54f, 1.0f, -0.452f, 0.0f, -0.172f, 0.532f, 1.0f,
+ -0.448f, 0.0f, -0.174f, 0.523f, 1.0f, -0.445f, 0.0f, -0.176f, 0.514f, 1.0f, -0.441f, 0.0f, -0.179f, 0.505f, 1.0f, -0.438f, 0.0f, -0.181f, 0.497f, 1.0f,
+ -0.435f, 0.0f, -0.183f, 0.488f, 1.0f, -0.431f, 0.0f, -0.185f, 0.48f, 1.0f, -0.428f, 0.0f, -0.188f, 0.472f, 1.0f, -0.425f, 0.0f, -0.19f, 0.464f, 1.0f,
+ -0.422f, 0.0f, -0.192f, 0.457f, 1.0f, -0.419f, 0.0f, -0.194f, 0.451f, 1.0f, -0.416f, 0.0f, -0.196f, 0.444f, 1.0f, -0.413f, 0.0f, -0.198f, 0.439f, 1.0f,
+ -0.41f, 0.0f, -0.2f, 0.434f, 1.0f, -0.407f, 0.0f, -0.202f, 0.429f, 1.0f, -0.404f, 0.0f, -0.204f, 0.426f, 1.0f, -0.401f, 0.0f, -0.206f, 0.422f, 1.0f,
+ -0.398f, 0.0f, -0.208f, 0.419f, 1.0f, -0.396f, 0.0f, -0.21f, 0.417f, 1.0f, -0.393f, 0.0f, -0.212f, 0.415f, 1.0f, -0.39f, 0.0f, -0.213f, 0.413f, 1.0f,
+ -0.388f, 0.0f, -0.215f, 0.412f, 1.0f, -0.385f, 0.0f, -0.217f, 0.411f, 1.0f, -0.382f, 0.0f, -0.219f, 0.41f, 1.0f, -0.38f, 0.0f, -0.221f, 0.41f, 1.0f,
+ -0.377f, 0.0f, -0.222f, 0.409f, 1.0f, -0.375f, 0.0f, -0.224f, 0.409f, 1.0f, -0.372f, 0.0f, -0.226f, 0.409f, 1.0f, -0.37f, 0.0f, -0.228f, 0.409f, 1.0f,
+ -0.367f, 0.0f, -0.229f, 0.409f, 1.0f, -0.365f, 0.0f, -0.231f, 0.409f, 1.0f, -0.362f, 0.0f, -0.233f, 0.409f, 1.0f, -0.36f, 0.0f, -0.235f, 0.409f, 1.0f,
+ -0.357f, 0.0f, -0.236f, 0.409f, 1.0f, -0.355f, 0.0f, -0.238f, 0.409f, 1.0f, -0.352f, 0.0f, -0.24f, 0.408f, 1.0f, -0.35f, 0.0f, -0.242f, 0.408f, 1.0f,
+ -0.348f, 0.0f, -0.243f, 0.407f, 1.0f, -0.345f, 0.0f, -0.245f, 0.406f, 1.0f, -0.343f, 0.0f, -0.247f, 0.405f, 1.0f, -0.34f, 0.0f, -0.249f, 0.404f, 1.0f,
+ -0.338f, 0.0f, -0.251f, 0.403f, 1.0f, -0.336f, 0.0f, -0.253f, 0.401f, 1.0f, -0.333f, 0.0f, -0.255f, 0.399f, 1.0f, -0.331f, 0.0f, -0.256f, 0.397f, 1.0f,
+ -0.329f, 0.0f, -0.258f, 0.394f, 1.0f, -0.327f, 0.0f, -0.26f, 0.391f, 1.0f, -0.324f, 0.0f, -0.262f, 0.387f, 1.0f, -0.322f, 0.0f, -0.264f, 0.383f, 1.0f,
+ -0.32f, 0.0f, -0.266f, 0.379f, 1.0f, -0.318f, 0.0f, -0.268f, 0.374f, 1.0f, -0.316f, 0.0f, -0.27f, 0.368f, 1.0f, -0.314f, 0.0f, -0.272f, 0.362f, 1.0f,
+ -0.312f, 0.0f, -0.275f, 0.356f, 1.0f, -0.309f, 0.0f, -0.277f, 0.349f, 1.0f, -0.307f, 0.0f, -0.279f, 0.341f, 1.0f, -0.305f, 0.0f, -0.281f, 0.333f, 1.0f,
+ -0.303f, 0.0f, -0.283f, 0.325f, 1.0f, -0.301f, 0.0f, -0.286f, 0.316f, 1.0f, -0.299f, 0.0f, -0.288f, 0.307f, 1.0f, -0.297f, 0.0f, -0.29f, 0.298f, 1.0f,
+ -0.295f, 0.0f, -0.293f, 0.289f, 1.0f, -0.293f, 0.0f, -0.295f, 0.279f, 1.0f, -0.291f, 0.0f, -0.298f, 0.269f, 1.0f, -0.29f, 0.0f, -0.3f, 0.259f, 1.0f,
+ -0.288f, 0.0f, -0.303f, 0.249f, 1.0f, -0.286f, 0.0f, -0.306f, 0.238f, 1.0f, -0.284f, 0.0f, -0.308f, 0.227f, 1.0f, -0.282f, 0.0f, -0.311f, 0.215f, 1.0f,
+ -0.28f, 0.0f, -0.314f, 0.203f, 1.0f, -0.278f, 0.0f, -0.317f, 0.191f, 1.0f, -0.277f, 0.0f, -0.32f, 0.178f, 1.0f, -0.275f, 0.0f, -0.323f, 0.165f, 1.0f,
+ -0.273f, 0.0f, -0.326f, 0.151f, 1.0f, -0.271f, 0.0f, -0.33f, 0.138f, 1.0f, -0.27f, 0.0f, -0.333f, 0.124f, 1.0f, -0.268f, 0.0f, -0.336f, 0.11f, 1.0f,
+ -0.267f, 0.0f, -0.34f, 0.097f, 1.0f, -0.265f, 0.0f, -0.343f, 0.085f, 1.0f, -0.264f, 0.0f, -0.346f, 0.073f, 1.0f, -0.262f, 0.0f, -0.35f, 0.062f, 1.0f,
+ -0.261f, 0.0f, -0.353f, 0.052f, 1.0f, -0.259f, 0.0f, -0.357f, 0.043f, 1.0f, -0.258f, 0.0f, -0.36f, 0.035f, 1.0f, -0.257f, 0.0f, -0.363f, 0.028f, 1.0f,
+ -0.255f, 0.0f, -0.366f, 0.021f, 1.0f, -0.254f, 0.0f, -0.369f, 0.016f, 1.0f, -0.253f, 0.0f, -0.372f, 0.01f, 1.0f, -0.252f, 0.0f, -0.375f, 0.006f, 1.0f,
+ -0.251f, 0.0f, -0.379f, 0.0f, 1.0f,
+};
+
+static const float data24[133 * GP_PRIM_DATABUF_SIZE] = {
+ 0.233f, 0.0f, -0.376f, 0.021f, 1.0f, 0.234f, 0.0f, -0.372f, 0.08f, 1.0f, 0.234f, 0.0f, -0.369f, 0.116f, 1.0f, 0.234f, 0.0f, -0.366f, 0.156f, 1.0f,
+ 0.235f, 0.0f, -0.362f, 0.191f, 1.0f, 0.236f, 0.0f, -0.359f, 0.222f, 1.0f, 0.236f, 0.0f, -0.356f, 0.248f, 1.0f, 0.237f, 0.0f, -0.353f, 0.27f, 1.0f,
+ 0.238f, 0.0f, -0.35f, 0.289f, 1.0f, 0.239f, 0.0f, -0.346f, 0.304f, 1.0f, 0.24f, 0.0f, -0.343f, 0.319f, 1.0f, 0.241f, 0.0f, -0.34f, 0.334f, 1.0f,
+ 0.242f, 0.0f, -0.337f, 0.35f, 1.0f, 0.243f, 0.0f, -0.335f, 0.367f, 1.0f, 0.244f, 0.0f, -0.332f, 0.385f, 1.0f, 0.245f, 0.0f, -0.329f, 0.401f, 1.0f,
+ 0.247f, 0.0f, -0.327f, 0.415f, 1.0f, 0.248f, 0.0f, -0.324f, 0.426f, 1.0f, 0.249f, 0.0f, -0.322f, 0.435f, 1.0f, 0.251f, 0.0f, -0.32f, 0.443f, 1.0f,
+ 0.252f, 0.0f, -0.318f, 0.449f, 1.0f, 0.254f, 0.0f, -0.316f, 0.455f, 1.0f, 0.255f, 0.0f, -0.314f, 0.461f, 1.0f, 0.257f, 0.0f, -0.312f, 0.467f, 1.0f,
+ 0.258f, 0.0f, -0.311f, 0.474f, 1.0f, 0.26f, 0.0f, -0.309f, 0.48f, 1.0f, 0.262f, 0.0f, -0.307f, 0.487f, 1.0f, 0.263f, 0.0f, -0.305f, 0.493f, 1.0f,
+ 0.265f, 0.0f, -0.303f, 0.499f, 1.0f, 0.267f, 0.0f, -0.3f, 0.505f, 1.0f, 0.269f, 0.0f, -0.298f, 0.511f, 1.0f, 0.271f, 0.0f, -0.296f, 0.518f, 1.0f,
+ 0.273f, 0.0f, -0.294f, 0.524f, 1.0f, 0.276f, 0.0f, -0.291f, 0.531f, 1.0f, 0.278f, 0.0f, -0.289f, 0.539f, 1.0f, 0.281f, 0.0f, -0.287f, 0.546f, 1.0f,
+ 0.283f, 0.0f, -0.284f, 0.552f, 1.0f, 0.286f, 0.0f, -0.281f, 0.557f, 1.0f, 0.289f, 0.0f, -0.279f, 0.561f, 1.0f, 0.292f, 0.0f, -0.276f, 0.565f, 1.0f,
+ 0.294f, 0.0f, -0.274f, 0.568f, 1.0f, 0.297f, 0.0f, -0.271f, 0.57f, 1.0f, 0.3f, 0.0f, -0.269f, 0.572f, 1.0f, 0.303f, 0.0f, -0.267f, 0.574f, 1.0f,
+ 0.306f, 0.0f, -0.264f, 0.575f, 1.0f, 0.308f, 0.0f, -0.262f, 0.576f, 1.0f, 0.311f, 0.0f, -0.26f, 0.577f, 1.0f, 0.314f, 0.0f, -0.257f, 0.578f, 1.0f,
+ 0.316f, 0.0f, -0.255f, 0.578f, 1.0f, 0.319f, 0.0f, -0.253f, 0.579f, 1.0f, 0.322f, 0.0f, -0.25f, 0.579f, 1.0f, 0.325f, 0.0f, -0.248f, 0.58f, 1.0f,
+ 0.328f, 0.0f, -0.246f, 0.58f, 1.0f, 0.331f, 0.0f, -0.243f, 0.58f, 1.0f, 0.334f, 0.0f, -0.241f, 0.58f, 1.0f, 0.337f, 0.0f, -0.239f, 0.58f, 1.0f,
+ 0.341f, 0.0f, -0.236f, 0.58f, 1.0f, 0.344f, 0.0f, -0.233f, 0.581f, 1.0f, 0.348f, 0.0f, -0.231f, 0.581f, 1.0f, 0.352f, 0.0f, -0.228f, 0.581f, 1.0f,
+ 0.356f, 0.0f, -0.225f, 0.582f, 1.0f, 0.36f, 0.0f, -0.222f, 0.582f, 1.0f, 0.365f, 0.0f, -0.219f, 0.582f, 1.0f, 0.369f, 0.0f, -0.216f, 0.582f, 1.0f,
+ 0.374f, 0.0f, -0.214f, 0.582f, 1.0f, 0.378f, 0.0f, -0.211f, 0.582f, 1.0f, 0.383f, 0.0f, -0.208f, 0.583f, 1.0f, 0.387f, 0.0f, -0.205f, 0.583f, 1.0f,
+ 0.392f, 0.0f, -0.202f, 0.583f, 1.0f, 0.397f, 0.0f, -0.199f, 0.583f, 1.0f, 0.401f, 0.0f, -0.197f, 0.583f, 1.0f, 0.406f, 0.0f, -0.194f, 0.583f, 1.0f,
+ 0.411f, 0.0f, -0.191f, 0.583f, 1.0f, 0.416f, 0.0f, -0.188f, 0.583f, 1.0f, 0.42f, 0.0f, -0.186f, 0.583f, 1.0f, 0.425f, 0.0f, -0.183f, 0.583f, 1.0f,
+ 0.43f, 0.0f, -0.18f, 0.583f, 1.0f, 0.434f, 0.0f, -0.178f, 0.583f, 1.0f, 0.439f, 0.0f, -0.175f, 0.583f, 1.0f, 0.444f, 0.0f, -0.172f, 0.583f, 1.0f,
+ 0.449f, 0.0f, -0.17f, 0.584f, 1.0f, 0.453f, 0.0f, -0.167f, 0.584f, 1.0f, 0.458f, 0.0f, -0.164f, 0.584f, 1.0f, 0.463f, 0.0f, -0.161f, 0.585f, 1.0f,
+ 0.468f, 0.0f, -0.158f, 0.585f, 1.0f, 0.473f, 0.0f, -0.155f, 0.585f, 1.0f, 0.478f, 0.0f, -0.152f, 0.585f, 1.0f, 0.483f, 0.0f, -0.149f, 0.585f, 1.0f,
+ 0.488f, 0.0f, -0.146f, 0.585f, 1.0f, 0.492f, 0.0f, -0.143f, 0.585f, 1.0f, 0.497f, 0.0f, -0.14f, 0.586f, 1.0f, 0.501f, 0.0f, -0.137f, 0.586f, 1.0f,
+ 0.506f, 0.0f, -0.134f, 0.586f, 1.0f, 0.51f, 0.0f, -0.13f, 0.586f, 1.0f, 0.515f, 0.0f, -0.127f, 0.586f, 1.0f, 0.52f, 0.0f, -0.124f, 0.586f, 1.0f,
+ 0.524f, 0.0f, -0.12f, 0.586f, 1.0f, 0.529f, 0.0f, -0.117f, 0.586f, 1.0f, 0.534f, 0.0f, -0.113f, 0.586f, 1.0f, 0.539f, 0.0f, -0.109f, 0.586f, 1.0f,
+ 0.544f, 0.0f, -0.105f, 0.586f, 1.0f, 0.55f, 0.0f, -0.1f, 0.586f, 1.0f, 0.555f, 0.0f, -0.095f, 0.586f, 1.0f, 0.561f, 0.0f, -0.09f, 0.586f, 1.0f,
+ 0.567f, 0.0f, -0.084f, 0.587f, 1.0f, 0.573f, 0.0f, -0.078f, 0.587f, 1.0f, 0.579f, 0.0f, -0.071f, 0.587f, 1.0f, 0.586f, 0.0f, -0.063f, 0.588f, 1.0f,
+ 0.593f, 0.0f, -0.055f, 0.588f, 1.0f, 0.6f, 0.0f, -0.047f, 0.588f, 1.0f, 0.607f, 0.0f, -0.038f, 0.589f, 1.0f, 0.614f, 0.0f, -0.028f, 0.589f, 1.0f,
+ 0.621f, 0.0f, -0.018f, 0.589f, 1.0f, 0.629f, 0.0f, -0.007f, 0.589f, 1.0f, 0.636f, 0.0f, 0.004f, 0.589f, 1.0f, 0.643f, 0.0f, 0.015f, 0.59f, 1.0f,
+ 0.65f, 0.0f, 0.026f, 0.589f, 1.0f, 0.656f, 0.0f, 0.038f, 0.589f, 1.0f, 0.663f, 0.0f, 0.049f, 0.588f, 1.0f, 0.669f, 0.0f, 0.06f, 0.587f, 1.0f,
+ 0.676f, 0.0f, 0.072f, 0.584f, 1.0f, 0.682f, 0.0f, 0.084f, 0.579f, 1.0f, 0.688f, 0.0f, 0.096f, 0.571f, 1.0f, 0.694f, 0.0f, 0.108f, 0.558f, 1.0f,
+ 0.7f, 0.0f, 0.12f, 0.54f, 1.0f, 0.706f, 0.0f, 0.133f, 0.514f, 1.0f, 0.712f, 0.0f, 0.145f, 0.478f, 1.0f, 0.718f, 0.0f, 0.158f, 0.431f, 1.0f,
+ 0.723f, 0.0f, 0.17f, 0.369f, 1.0f, 0.728f, 0.0f, 0.182f, 0.294f, 1.0f, 0.733f, 0.0f, 0.194f, 0.205f, 1.0f, 0.737f, 0.0f, 0.204f, 0.125f, 1.0f,
+ 0.743f, 0.0f, 0.218f, 0.0f, 1.0f,
+};
+
+static const float data25[389 * GP_PRIM_DATABUF_SIZE] = {
+ -0.284f, 0.0f, -0.444f, 0.0f, 1.0f, -0.285f, 0.0f, -0.448f, 0.0f, 1.0f, -0.285f, 0.0f, -0.45f, 0.0f, 1.0f, -0.286f, 0.0f, -0.454f, 0.0f, 1.0f,
+ -0.286f, 0.0f, -0.457f, 0.0f, 1.0f, -0.287f, 0.0f, -0.46f, 0.0f, 1.0f, -0.288f, 0.0f, -0.463f, 0.0f, 1.0f, -0.289f, 0.0f, -0.466f, 0.0f, 1.0f,
+ -0.289f, 0.0f, -0.47f, 0.0f, 1.0f, -0.29f, 0.0f, -0.473f, 0.0f, 1.0f, -0.291f, 0.0f, -0.476f, 0.0f, 1.0f, -0.292f, 0.0f, -0.48f, 0.0f, 1.0f,
+ -0.293f, 0.0f, -0.484f, 0.0f, 1.0f, -0.294f, 0.0f, -0.487f, 0.0f, 1.0f, -0.295f, 0.0f, -0.491f, 0.0f, 1.0f, -0.296f, 0.0f, -0.494f, 0.0f, 1.0f,
+ -0.297f, 0.0f, -0.498f, 0.0f, 1.0f, -0.298f, 0.0f, -0.502f, 0.0f, 1.0f, -0.299f, 0.0f, -0.505f, 0.0f, 1.0f, -0.3f, 0.0f, -0.509f, 0.0f, 1.0f,
+ -0.301f, 0.0f, -0.513f, 0.0f, 1.0f, -0.302f, 0.0f, -0.517f, 0.0f, 1.0f, -0.303f, 0.0f, -0.52f, 0.0f, 1.0f, -0.304f, 0.0f, -0.524f, 0.0f, 1.0f,
+ -0.305f, 0.0f, -0.528f, 0.0f, 1.0f, -0.306f, 0.0f, -0.532f, 0.0f, 1.0f, -0.307f, 0.0f, -0.535f, 0.0f, 1.0f, -0.308f, 0.0f, -0.539f, 0.0f, 1.0f,
+ -0.309f, 0.0f, -0.543f, 0.0f, 1.0f, -0.31f, 0.0f, -0.547f, 0.0f, 1.0f, -0.311f, 0.0f, -0.55f, 0.0f, 1.0f, -0.312f, 0.0f, -0.554f, 0.0f, 1.0f,
+ -0.313f, 0.0f, -0.558f, 0.0f, 1.0f, -0.314f, 0.0f, -0.562f, 0.0f, 1.0f, -0.315f, 0.0f, -0.565f, 0.0f, 1.0f, -0.316f, 0.0f, -0.569f, 0.0f, 1.0f,
+ -0.317f, 0.0f, -0.573f, 0.0f, 1.0f, -0.318f, 0.0f, -0.576f, 0.0f, 1.0f, -0.319f, 0.0f, -0.58f, 0.0f, 1.0f, -0.32f, 0.0f, -0.583f, 0.0f, 1.0f,
+ -0.321f, 0.0f, -0.587f, 0.0f, 1.0f, -0.322f, 0.0f, -0.591f, 0.0f, 1.0f, -0.323f, 0.0f, -0.594f, 0.0f, 1.0f, -0.323f, 0.0f, -0.598f, 0.0f, 1.0f,
+ -0.324f, 0.0f, -0.601f, 0.0f, 1.0f, -0.325f, 0.0f, -0.605f, 0.0f, 1.0f, -0.326f, 0.0f, -0.608f, 0.0f, 1.0f, -0.326f, 0.0f, -0.612f, 0.0f, 1.0f,
+ -0.327f, 0.0f, -0.615f, 0.0f, 1.0f, -0.328f, 0.0f, -0.619f, 0.0f, 1.0f, -0.328f, 0.0f, -0.622f, 0.0f, 1.0f, -0.329f, 0.0f, -0.625f, 0.0f, 1.0f,
+ -0.33f, 0.0f, -0.629f, 0.0f, 1.0f, -0.33f, 0.0f, -0.632f, 0.0f, 1.0f, -0.331f, 0.0f, -0.635f, 0.001f, 1.0f, -0.331f, 0.0f, -0.639f, 0.001f, 1.0f,
+ -0.332f, 0.0f, -0.642f, 0.002f, 1.0f, -0.332f, 0.0f, -0.645f, 0.002f, 1.0f, -0.333f, 0.0f, -0.649f, 0.003f, 1.0f, -0.333f, 0.0f, -0.652f, 0.005f, 1.0f,
+ -0.334f, 0.0f, -0.655f, 0.006f, 1.0f, -0.334f, 0.0f, -0.658f, 0.009f, 1.0f, -0.335f, 0.0f, -0.662f, 0.011f, 1.0f, -0.335f, 0.0f, -0.665f, 0.015f, 1.0f,
+ -0.335f, 0.0f, -0.668f, 0.019f, 1.0f, -0.336f, 0.0f, -0.672f, 0.024f, 1.0f, -0.336f, 0.0f, -0.675f, 0.031f, 1.0f, -0.337f, 0.0f, -0.678f, 0.038f, 1.0f,
+ -0.337f, 0.0f, -0.682f, 0.046f, 1.0f, -0.337f, 0.0f, -0.685f, 0.056f, 1.0f, -0.338f, 0.0f, -0.689f, 0.067f, 1.0f, -0.338f, 0.0f, -0.692f, 0.079f, 1.0f,
+ -0.338f, 0.0f, -0.696f, 0.093f, 1.0f, -0.339f, 0.0f, -0.699f, 0.107f, 1.0f, -0.339f, 0.0f, -0.703f, 0.123f, 1.0f, -0.34f, 0.0f, -0.706f, 0.139f, 1.0f,
+ -0.34f, 0.0f, -0.71f, 0.157f, 1.0f, -0.34f, 0.0f, -0.714f, 0.174f, 1.0f, -0.34f, 0.0f, -0.717f, 0.193f, 1.0f, -0.341f, 0.0f, -0.721f, 0.211f, 1.0f,
+ -0.341f, 0.0f, -0.725f, 0.23f, 1.0f, -0.341f, 0.0f, -0.729f, 0.248f, 1.0f, -0.342f, 0.0f, -0.732f, 0.266f, 1.0f, -0.342f, 0.0f, -0.736f, 0.284f, 1.0f,
+ -0.342f, 0.0f, -0.74f, 0.302f, 1.0f, -0.342f, 0.0f, -0.744f, 0.318f, 1.0f, -0.342f, 0.0f, -0.748f, 0.334f, 1.0f, -0.342f, 0.0f, -0.752f, 0.349f, 1.0f,
+ -0.343f, 0.0f, -0.756f, 0.364f, 1.0f, -0.343f, 0.0f, -0.76f, 0.377f, 1.0f, -0.343f, 0.0f, -0.763f, 0.389f, 1.0f, -0.343f, 0.0f, -0.767f, 0.401f, 1.0f,
+ -0.343f, 0.0f, -0.771f, 0.411f, 1.0f, -0.343f, 0.0f, -0.775f, 0.421f, 1.0f, -0.342f, 0.0f, -0.779f, 0.429f, 1.0f, -0.342f, 0.0f, -0.783f, 0.437f, 1.0f,
+ -0.342f, 0.0f, -0.786f, 0.444f, 1.0f, -0.342f, 0.0f, -0.79f, 0.451f, 1.0f, -0.342f, 0.0f, -0.794f, 0.456f, 1.0f, -0.341f, 0.0f, -0.797f, 0.461f, 1.0f,
+ -0.341f, 0.0f, -0.801f, 0.466f, 1.0f, -0.34f, 0.0f, -0.805f, 0.469f, 1.0f, -0.34f, 0.0f, -0.808f, 0.473f, 1.0f, -0.339f, 0.0f, -0.812f, 0.476f, 1.0f,
+ -0.339f, 0.0f, -0.815f, 0.478f, 1.0f, -0.338f, 0.0f, -0.818f, 0.48f, 1.0f, -0.338f, 0.0f, -0.822f, 0.482f, 1.0f, -0.337f, 0.0f, -0.825f, 0.483f, 1.0f,
+ -0.336f, 0.0f, -0.828f, 0.484f, 1.0f, -0.335f, 0.0f, -0.831f, 0.485f, 1.0f, -0.334f, 0.0f, -0.834f, 0.486f, 1.0f, -0.333f, 0.0f, -0.837f, 0.487f, 1.0f,
+ -0.332f, 0.0f, -0.84f, 0.487f, 1.0f, -0.331f, 0.0f, -0.843f, 0.487f, 1.0f, -0.33f, 0.0f, -0.846f, 0.488f, 1.0f, -0.329f, 0.0f, -0.849f, 0.488f, 1.0f,
+ -0.328f, 0.0f, -0.852f, 0.488f, 1.0f, -0.326f, 0.0f, -0.855f, 0.488f, 1.0f, -0.325f, 0.0f, -0.857f, 0.488f, 1.0f, -0.324f, 0.0f, -0.86f, 0.488f, 1.0f,
+ -0.322f, 0.0f, -0.863f, 0.488f, 1.0f, -0.321f, 0.0f, -0.865f, 0.488f, 1.0f, -0.319f, 0.0f, -0.868f, 0.488f, 1.0f, -0.318f, 0.0f, -0.871f, 0.488f, 1.0f,
+ -0.316f, 0.0f, -0.873f, 0.489f, 1.0f, -0.314f, 0.0f, -0.876f, 0.489f, 1.0f, -0.312f, 0.0f, -0.878f, 0.489f, 1.0f, -0.311f, 0.0f, -0.881f, 0.489f, 1.0f,
+ -0.309f, 0.0f, -0.883f, 0.489f, 1.0f, -0.307f, 0.0f, -0.885f, 0.489f, 1.0f, -0.305f, 0.0f, -0.888f, 0.49f, 1.0f, -0.303f, 0.0f, -0.89f, 0.491f, 1.0f,
+ -0.301f, 0.0f, -0.892f, 0.491f, 1.0f, -0.298f, 0.0f, -0.894f, 0.492f, 1.0f, -0.296f, 0.0f, -0.897f, 0.494f, 1.0f, -0.294f, 0.0f, -0.899f, 0.495f, 1.0f,
+ -0.292f, 0.0f, -0.901f, 0.497f, 1.0f, -0.289f, 0.0f, -0.903f, 0.5f, 1.0f, -0.287f, 0.0f, -0.905f, 0.502f, 1.0f, -0.284f, 0.0f, -0.907f, 0.505f, 1.0f,
+ -0.282f, 0.0f, -0.909f, 0.509f, 1.0f, -0.279f, 0.0f, -0.912f, 0.512f, 1.0f, -0.277f, 0.0f, -0.914f, 0.517f, 1.0f, -0.274f, 0.0f, -0.916f, 0.521f, 1.0f,
+ -0.271f, 0.0f, -0.918f, 0.526f, 1.0f, -0.269f, 0.0f, -0.919f, 0.531f, 1.0f, -0.266f, 0.0f, -0.921f, 0.537f, 1.0f, -0.263f, 0.0f, -0.923f, 0.543f, 1.0f,
+ -0.26f, 0.0f, -0.925f, 0.548f, 1.0f, -0.257f, 0.0f, -0.927f, 0.554f, 1.0f, -0.255f, 0.0f, -0.929f, 0.56f, 1.0f, -0.252f, 0.0f, -0.931f, 0.566f, 1.0f,
+ -0.249f, 0.0f, -0.932f, 0.571f, 1.0f, -0.246f, 0.0f, -0.934f, 0.577f, 1.0f, -0.243f, 0.0f, -0.936f, 0.582f, 1.0f, -0.24f, 0.0f, -0.938f, 0.587f, 1.0f,
+ -0.237f, 0.0f, -0.939f, 0.592f, 1.0f, -0.234f, 0.0f, -0.941f, 0.597f, 1.0f, -0.231f, 0.0f, -0.943f, 0.601f, 1.0f, -0.228f, 0.0f, -0.944f, 0.605f, 1.0f,
+ -0.225f, 0.0f, -0.946f, 0.609f, 1.0f, -0.222f, 0.0f, -0.948f, 0.613f, 1.0f, -0.219f, 0.0f, -0.949f, 0.617f, 1.0f, -0.216f, 0.0f, -0.951f, 0.62f, 1.0f,
+ -0.213f, 0.0f, -0.953f, 0.624f, 1.0f, -0.21f, 0.0f, -0.954f, 0.627f, 1.0f, -0.207f, 0.0f, -0.956f, 0.63f, 1.0f, -0.204f, 0.0f, -0.958f, 0.633f, 1.0f,
+ -0.201f, 0.0f, -0.959f, 0.636f, 1.0f, -0.198f, 0.0f, -0.961f, 0.639f, 1.0f, -0.195f, 0.0f, -0.962f, 0.641f, 1.0f, -0.191f, 0.0f, -0.964f, 0.643f, 1.0f,
+ -0.188f, 0.0f, -0.965f, 0.646f, 1.0f, -0.185f, 0.0f, -0.967f, 0.648f, 1.0f, -0.181f, 0.0f, -0.968f, 0.649f, 1.0f, -0.178f, 0.0f, -0.969f, 0.651f, 1.0f,
+ -0.175f, 0.0f, -0.971f, 0.653f, 1.0f, -0.171f, 0.0f, -0.972f, 0.654f, 1.0f, -0.168f, 0.0f, -0.973f, 0.655f, 1.0f, -0.165f, 0.0f, -0.974f, 0.657f, 1.0f,
+ -0.161f, 0.0f, -0.976f, 0.658f, 1.0f, -0.158f, 0.0f, -0.977f, 0.659f, 1.0f, -0.154f, 0.0f, -0.978f, 0.66f, 1.0f, -0.151f, 0.0f, -0.979f, 0.661f, 1.0f,
+ -0.148f, 0.0f, -0.98f, 0.662f, 1.0f, -0.144f, 0.0f, -0.981f, 0.664f, 1.0f, -0.141f, 0.0f, -0.982f, 0.665f, 1.0f, -0.137f, 0.0f, -0.983f, 0.667f, 1.0f,
+ -0.134f, 0.0f, -0.984f, 0.669f, 1.0f, -0.13f, 0.0f, -0.985f, 0.671f, 1.0f, -0.127f, 0.0f, -0.986f, 0.673f, 1.0f, -0.124f, 0.0f, -0.987f, 0.675f, 1.0f,
+ -0.12f, 0.0f, -0.988f, 0.678f, 1.0f, -0.117f, 0.0f, -0.989f, 0.68f, 1.0f, -0.113f, 0.0f, -0.99f, 0.683f, 1.0f, -0.11f, 0.0f, -0.991f, 0.685f, 1.0f,
+ -0.107f, 0.0f, -0.992f, 0.688f, 1.0f, -0.103f, 0.0f, -0.992f, 0.691f, 1.0f, -0.1f, 0.0f, -0.993f, 0.693f, 1.0f, -0.097f, 0.0f, -0.994f, 0.696f, 1.0f,
+ -0.093f, 0.0f, -0.995f, 0.698f, 1.0f, -0.09f, 0.0f, -0.996f, 0.701f, 1.0f, -0.087f, 0.0f, -0.997f, 0.703f, 1.0f, -0.084f, 0.0f, -0.997f, 0.705f, 1.0f,
+ -0.08f, 0.0f, -0.998f, 0.707f, 1.0f, -0.077f, 0.0f, -0.999f, 0.708f, 1.0f, -0.074f, 0.0f, -1.0f, 0.71f, 1.0f, -0.07f, 0.0f, -1.0f, 0.712f, 1.0f,
+ -0.067f, 0.0f, -1.001f, 0.713f, 1.0f, -0.063f, 0.0f, -1.002f, 0.715f, 1.0f, -0.06f, 0.0f, -1.002f, 0.717f, 1.0f, -0.056f, 0.0f, -1.003f, 0.718f, 1.0f,
+ -0.053f, 0.0f, -1.003f, 0.72f, 1.0f, -0.049f, 0.0f, -1.004f, 0.723f, 1.0f, -0.045f, 0.0f, -1.004f, 0.725f, 1.0f, -0.041f, 0.0f, -1.005f, 0.728f, 1.0f,
+ -0.038f, 0.0f, -1.005f, 0.73f, 1.0f, -0.034f, 0.0f, -1.006f, 0.733f, 1.0f, -0.03f, 0.0f, -1.006f, 0.736f, 1.0f, -0.026f, 0.0f, -1.007f, 0.738f, 1.0f,
+ -0.022f, 0.0f, -1.007f, 0.741f, 1.0f, -0.018f, 0.0f, -1.007f, 0.743f, 1.0f, -0.014f, 0.0f, -1.008f, 0.746f, 1.0f, -0.01f, 0.0f, -1.008f, 0.748f, 1.0f,
+ -0.006f, 0.0f, -1.009f, 0.75f, 1.0f, -0.001f, 0.0f, -1.009f, 0.752f, 1.0f, 0.003f, 0.0f, -1.009f, 0.754f, 1.0f, 0.007f, 0.0f, -1.01f, 0.755f, 1.0f,
+ 0.011f, 0.0f, -1.01f, 0.757f, 1.0f, 0.015f, 0.0f, -1.01f, 0.758f, 1.0f, 0.02f, 0.0f, -1.011f, 0.759f, 1.0f, 0.024f, 0.0f, -1.011f, 0.76f, 1.0f,
+ 0.028f, 0.0f, -1.011f, 0.761f, 1.0f, 0.033f, 0.0f, -1.011f, 0.761f, 1.0f, 0.037f, 0.0f, -1.012f, 0.762f, 1.0f, 0.041f, 0.0f, -1.012f, 0.762f, 1.0f,
+ 0.045f, 0.0f, -1.012f, 0.763f, 1.0f, 0.05f, 0.0f, -1.012f, 0.763f, 1.0f, 0.054f, 0.0f, -1.012f, 0.764f, 1.0f, 0.058f, 0.0f, -1.013f, 0.764f, 1.0f,
+ 0.062f, 0.0f, -1.013f, 0.764f, 1.0f, 0.066f, 0.0f, -1.013f, 0.764f, 1.0f, 0.071f, 0.0f, -1.013f, 0.764f, 1.0f, 0.075f, 0.0f, -1.013f, 0.765f, 1.0f,
+ 0.079f, 0.0f, -1.013f, 0.765f, 1.0f, 0.083f, 0.0f, -1.013f, 0.765f, 1.0f, 0.087f, 0.0f, -1.013f, 0.765f, 1.0f, 0.091f, 0.0f, -1.013f, 0.765f, 1.0f,
+ 0.095f, 0.0f, -1.013f, 0.765f, 1.0f, 0.099f, 0.0f, -1.013f, 0.766f, 1.0f, 0.103f, 0.0f, -1.013f, 0.766f, 1.0f, 0.108f, 0.0f, -1.012f, 0.766f, 1.0f,
+ 0.112f, 0.0f, -1.012f, 0.766f, 1.0f, 0.116f, 0.0f, -1.012f, 0.766f, 1.0f, 0.119f, 0.0f, -1.012f, 0.767f, 1.0f, 0.123f, 0.0f, -1.011f, 0.767f, 1.0f,
+ 0.127f, 0.0f, -1.011f, 0.767f, 1.0f, 0.131f, 0.0f, -1.01f, 0.767f, 1.0f, 0.135f, 0.0f, -1.01f, 0.767f, 1.0f, 0.139f, 0.0f, -1.009f, 0.768f, 1.0f,
+ 0.143f, 0.0f, -1.009f, 0.768f, 1.0f, 0.147f, 0.0f, -1.008f, 0.768f, 1.0f, 0.151f, 0.0f, -1.007f, 0.769f, 1.0f, 0.154f, 0.0f, -1.007f, 0.769f, 1.0f,
+ 0.158f, 0.0f, -1.006f, 0.769f, 1.0f, 0.162f, 0.0f, -1.005f, 0.769f, 1.0f, 0.166f, 0.0f, -1.004f, 0.77f, 1.0f, 0.17f, 0.0f, -1.003f, 0.77f, 1.0f,
+ 0.173f, 0.0f, -1.003f, 0.77f, 1.0f, 0.177f, 0.0f, -1.002f, 0.771f, 1.0f, 0.181f, 0.0f, -1.001f, 0.771f, 1.0f, 0.184f, 0.0f, -1.0f, 0.772f, 1.0f,
+ 0.188f, 0.0f, -0.999f, 0.772f, 1.0f, 0.192f, 0.0f, -0.998f, 0.773f, 1.0f, 0.195f, 0.0f, -0.997f, 0.773f, 1.0f, 0.199f, 0.0f, -0.996f, 0.774f, 1.0f,
+ 0.202f, 0.0f, -0.995f, 0.774f, 1.0f, 0.206f, 0.0f, -0.994f, 0.775f, 1.0f, 0.209f, 0.0f, -0.993f, 0.776f, 1.0f, 0.213f, 0.0f, -0.992f, 0.776f, 1.0f,
+ 0.216f, 0.0f, -0.991f, 0.777f, 1.0f, 0.22f, 0.0f, -0.99f, 0.777f, 1.0f, 0.223f, 0.0f, -0.988f, 0.778f, 1.0f, 0.227f, 0.0f, -0.987f, 0.778f, 1.0f,
+ 0.23f, 0.0f, -0.986f, 0.778f, 1.0f, 0.233f, 0.0f, -0.985f, 0.779f, 1.0f, 0.237f, 0.0f, -0.983f, 0.779f, 1.0f, 0.24f, 0.0f, -0.982f, 0.779f, 1.0f,
+ 0.243f, 0.0f, -0.981f, 0.779f, 1.0f, 0.246f, 0.0f, -0.979f, 0.778f, 1.0f, 0.249f, 0.0f, -0.978f, 0.778f, 1.0f, 0.252f, 0.0f, -0.976f, 0.777f, 1.0f,
+ 0.255f, 0.0f, -0.975f, 0.777f, 1.0f, 0.258f, 0.0f, -0.973f, 0.776f, 1.0f, 0.261f, 0.0f, -0.972f, 0.775f, 1.0f, 0.264f, 0.0f, -0.97f, 0.773f, 1.0f,
+ 0.267f, 0.0f, -0.968f, 0.772f, 1.0f, 0.269f, 0.0f, -0.967f, 0.77f, 1.0f, 0.272f, 0.0f, -0.965f, 0.769f, 1.0f, 0.275f, 0.0f, -0.963f, 0.767f, 1.0f,
+ 0.277f, 0.0f, -0.961f, 0.765f, 1.0f, 0.279f, 0.0f, -0.959f, 0.763f, 1.0f, 0.282f, 0.0f, -0.957f, 0.761f, 1.0f, 0.284f, 0.0f, -0.955f, 0.759f, 1.0f,
+ 0.286f, 0.0f, -0.953f, 0.756f, 1.0f, 0.288f, 0.0f, -0.951f, 0.754f, 1.0f, 0.29f, 0.0f, -0.948f, 0.752f, 1.0f, 0.292f, 0.0f, -0.946f, 0.749f, 1.0f,
+ 0.294f, 0.0f, -0.944f, 0.746f, 1.0f, 0.296f, 0.0f, -0.941f, 0.744f, 1.0f, 0.298f, 0.0f, -0.939f, 0.741f, 1.0f, 0.3f, 0.0f, -0.937f, 0.738f, 1.0f,
+ 0.302f, 0.0f, -0.934f, 0.736f, 1.0f, 0.303f, 0.0f, -0.932f, 0.733f, 1.0f, 0.305f, 0.0f, -0.929f, 0.73f, 1.0f, 0.306f, 0.0f, -0.926f, 0.727f, 1.0f,
+ 0.308f, 0.0f, -0.924f, 0.724f, 1.0f, 0.309f, 0.0f, -0.921f, 0.721f, 1.0f, 0.311f, 0.0f, -0.918f, 0.719f, 1.0f, 0.312f, 0.0f, -0.916f, 0.716f, 1.0f,
+ 0.313f, 0.0f, -0.913f, 0.713f, 1.0f, 0.315f, 0.0f, -0.91f, 0.71f, 1.0f, 0.316f, 0.0f, -0.907f, 0.707f, 1.0f, 0.317f, 0.0f, -0.904f, 0.704f, 1.0f,
+ 0.318f, 0.0f, -0.901f, 0.7f, 1.0f, 0.319f, 0.0f, -0.898f, 0.697f, 1.0f, 0.32f, 0.0f, -0.895f, 0.693f, 1.0f, 0.321f, 0.0f, -0.892f, 0.69f, 1.0f,
+ 0.322f, 0.0f, -0.889f, 0.686f, 1.0f, 0.323f, 0.0f, -0.886f, 0.681f, 1.0f, 0.324f, 0.0f, -0.883f, 0.677f, 1.0f, 0.325f, 0.0f, -0.88f, 0.672f, 1.0f,
+ 0.326f, 0.0f, -0.876f, 0.667f, 1.0f, 0.326f, 0.0f, -0.873f, 0.661f, 1.0f, 0.327f, 0.0f, -0.87f, 0.655f, 1.0f, 0.328f, 0.0f, -0.867f, 0.649f, 1.0f,
+ 0.329f, 0.0f, -0.864f, 0.643f, 1.0f, 0.329f, 0.0f, -0.861f, 0.637f, 1.0f, 0.33f, 0.0f, -0.857f, 0.63f, 1.0f, 0.331f, 0.0f, -0.854f, 0.624f, 1.0f,
+ 0.331f, 0.0f, -0.851f, 0.618f, 1.0f, 0.332f, 0.0f, -0.848f, 0.613f, 1.0f, 0.333f, 0.0f, -0.845f, 0.607f, 1.0f, 0.333f, 0.0f, -0.841f, 0.603f, 1.0f,
+ 0.334f, 0.0f, -0.838f, 0.598f, 1.0f, 0.334f, 0.0f, -0.835f, 0.594f, 1.0f, 0.335f, 0.0f, -0.832f, 0.591f, 1.0f, 0.335f, 0.0f, -0.828f, 0.588f, 1.0f,
+ 0.335f, 0.0f, -0.825f, 0.586f, 1.0f, 0.336f, 0.0f, -0.821f, 0.584f, 1.0f, 0.336f, 0.0f, -0.818f, 0.582f, 1.0f, 0.336f, 0.0f, -0.814f, 0.581f, 1.0f,
+ 0.337f, 0.0f, -0.811f, 0.58f, 1.0f, 0.337f, 0.0f, -0.807f, 0.58f, 1.0f, 0.337f, 0.0f, -0.803f, 0.579f, 1.0f, 0.337f, 0.0f, -0.799f, 0.579f, 1.0f,
+ 0.337f, 0.0f, -0.795f, 0.578f, 1.0f, 0.337f, 0.0f, -0.79f, 0.578f, 1.0f, 0.337f, 0.0f, -0.786f, 0.578f, 1.0f, 0.338f, 0.0f, -0.782f, 0.577f, 1.0f,
+ 0.338f, 0.0f, -0.777f, 0.576f, 1.0f, 0.337f, 0.0f, -0.772f, 0.574f, 1.0f, 0.337f, 0.0f, -0.767f, 0.572f, 1.0f, 0.337f, 0.0f, -0.762f, 0.569f, 1.0f,
+ 0.337f, 0.0f, -0.756f, 0.565f, 1.0f, 0.337f, 0.0f, -0.751f, 0.559f, 1.0f, 0.337f, 0.0f, -0.745f, 0.553f, 1.0f, 0.336f, 0.0f, -0.739f, 0.544f, 1.0f,
+ 0.336f, 0.0f, -0.732f, 0.534f, 1.0f, 0.335f, 0.0f, -0.725f, 0.521f, 1.0f, 0.334f, 0.0f, -0.718f, 0.505f, 1.0f, 0.333f, 0.0f, -0.711f, 0.487f, 1.0f,
+ 0.332f, 0.0f, -0.703f, 0.466f, 1.0f, 0.331f, 0.0f, -0.694f, 0.441f, 1.0f, 0.33f, 0.0f, -0.686f, 0.413f, 1.0f, 0.328f, 0.0f, -0.677f, 0.383f, 1.0f,
+ 0.326f, 0.0f, -0.667f, 0.35f, 1.0f, 0.325f, 0.0f, -0.657f, 0.316f, 1.0f, 0.323f, 0.0f, -0.647f, 0.281f, 1.0f, 0.32f, 0.0f, -0.636f, 0.246f, 1.0f,
+ 0.318f, 0.0f, -0.625f, 0.212f, 1.0f, 0.316f, 0.0f, -0.614f, 0.18f, 1.0f, 0.313f, 0.0f, -0.603f, 0.149f, 1.0f, 0.311f, 0.0f, -0.592f, 0.12f, 1.0f,
+ 0.308f, 0.0f, -0.581f, 0.093f, 1.0f, 0.306f, 0.0f, -0.57f, 0.069f, 1.0f, 0.303f, 0.0f, -0.559f, 0.046f, 1.0f, 0.301f, 0.0f, -0.55f, 0.027f, 1.0f,
+ 0.298f, 0.0f, -0.537f, 0.0f, 1.0f,
+};
+
+static const float data26[41 * GP_PRIM_DATABUF_SIZE] = {
+ -0.104f, 0.0f, -0.795f, 0.258f, 1.0f, -0.1f, 0.0f, -0.799f, 0.28f, 1.0f, -0.097f, 0.0f, -0.801f, 0.294f, 1.0f, -0.094f, 0.0f, -0.805f, 0.312f, 1.0f,
+ -0.09f, 0.0f, -0.808f, 0.328f, 1.0f, -0.086f, 0.0f, -0.811f, 0.345f, 1.0f, -0.082f, 0.0f, -0.815f, 0.361f, 1.0f, -0.078f, 0.0f, -0.818f, 0.377f, 1.0f,
+ -0.073f, 0.0f, -0.821f, 0.392f, 1.0f, -0.068f, 0.0f, -0.824f, 0.407f, 1.0f, -0.063f, 0.0f, -0.827f, 0.421f, 1.0f, -0.057f, 0.0f, -0.83f, 0.435f, 1.0f,
+ -0.051f, 0.0f, -0.833f, 0.448f, 1.0f, -0.045f, 0.0f, -0.835f, 0.46f, 1.0f, -0.039f, 0.0f, -0.837f, 0.471f, 1.0f, -0.033f, 0.0f, -0.839f, 0.481f, 1.0f,
+ -0.026f, 0.0f, -0.841f, 0.491f, 1.0f, -0.019f, 0.0f, -0.842f, 0.5f, 1.0f, -0.012f, 0.0f, -0.843f, 0.508f, 1.0f, -0.005f, 0.0f, -0.843f, 0.515f, 1.0f,
+ 0.002f, 0.0f, -0.843f, 0.522f, 1.0f, 0.009f, 0.0f, -0.843f, 0.527f, 1.0f, 0.016f, 0.0f, -0.842f, 0.532f, 1.0f, 0.023f, 0.0f, -0.841f, 0.535f, 1.0f,
+ 0.03f, 0.0f, -0.839f, 0.538f, 1.0f, 0.037f, 0.0f, -0.837f, 0.538f, 1.0f, 0.044f, 0.0f, -0.835f, 0.537f, 1.0f, 0.05f, 0.0f, -0.833f, 0.532f, 1.0f,
+ 0.056f, 0.0f, -0.83f, 0.524f, 1.0f, 0.062f, 0.0f, -0.827f, 0.513f, 1.0f, 0.068f, 0.0f, -0.823f, 0.496f, 1.0f, 0.074f, 0.0f, -0.82f, 0.474f, 1.0f,
+ 0.079f, 0.0f, -0.817f, 0.446f, 1.0f, 0.084f, 0.0f, -0.813f, 0.411f, 1.0f, 0.089f, 0.0f, -0.809f, 0.37f, 1.0f, 0.093f, 0.0f, -0.806f, 0.323f, 1.0f,
+ 0.098f, 0.0f, -0.802f, 0.269f, 1.0f, 0.102f, 0.0f, -0.798f, 0.211f, 1.0f, 0.106f, 0.0f, -0.795f, 0.146f, 1.0f, 0.109f, 0.0f, -0.792f, 0.089f, 1.0f,
+ 0.114f, 0.0f, -0.787f, 0.0f, 1.0f,
+};
+
+static const float data27[77 * GP_PRIM_DATABUF_SIZE] = {
+ -0.105f, 0.0f, -0.259f, 0.214f, 1.0f, -0.103f, 0.0f, -0.253f, 0.263f, 1.0f, -0.101f, 0.0f, -0.249f, 0.291f, 1.0f, -0.099f, 0.0f, -0.244f, 0.324f, 1.0f,
+ -0.098f, 0.0f, -0.24f, 0.351f, 1.0f, -0.096f, 0.0f, -0.235f, 0.376f, 1.0f, -0.094f, 0.0f, -0.231f, 0.397f, 1.0f, -0.092f, 0.0f, -0.227f, 0.416f, 1.0f,
+ -0.09f, 0.0f, -0.222f, 0.432f, 1.0f, -0.088f, 0.0f, -0.218f, 0.446f, 1.0f, -0.086f, 0.0f, -0.215f, 0.458f, 1.0f, -0.084f, 0.0f, -0.211f, 0.469f, 1.0f,
+ -0.082f, 0.0f, -0.208f, 0.478f, 1.0f, -0.079f, 0.0f, -0.205f, 0.486f, 1.0f, -0.077f, 0.0f, -0.203f, 0.494f, 1.0f, -0.075f, 0.0f, -0.2f, 0.501f, 1.0f,
+ -0.073f, 0.0f, -0.198f, 0.508f, 1.0f, -0.071f, 0.0f, -0.197f, 0.515f, 1.0f, -0.068f, 0.0f, -0.195f, 0.521f, 1.0f, -0.066f, 0.0f, -0.194f, 0.528f, 1.0f,
+ -0.064f, 0.0f, -0.194f, 0.534f, 1.0f, -0.061f, 0.0f, -0.194f, 0.54f, 1.0f, -0.059f, 0.0f, -0.194f, 0.546f, 1.0f, -0.056f, 0.0f, -0.194f, 0.551f, 1.0f,
+ -0.054f, 0.0f, -0.195f, 0.555f, 1.0f, -0.051f, 0.0f, -0.196f, 0.559f, 1.0f, -0.049f, 0.0f, -0.198f, 0.562f, 1.0f, -0.046f, 0.0f, -0.2f, 0.565f, 1.0f,
+ -0.044f, 0.0f, -0.201f, 0.567f, 1.0f, -0.041f, 0.0f, -0.204f, 0.568f, 1.0f, -0.039f, 0.0f, -0.206f, 0.569f, 1.0f, -0.036f, 0.0f, -0.208f, 0.57f, 1.0f,
+ -0.034f, 0.0f, -0.21f, 0.571f, 1.0f, -0.032f, 0.0f, -0.213f, 0.571f, 1.0f, -0.029f, 0.0f, -0.215f, 0.571f, 1.0f, -0.027f, 0.0f, -0.217f, 0.572f, 1.0f,
+ -0.024f, 0.0f, -0.219f, 0.572f, 1.0f, -0.022f, 0.0f, -0.221f, 0.572f, 1.0f, -0.019f, 0.0f, -0.222f, 0.572f, 1.0f, -0.016f, 0.0f, -0.224f, 0.572f, 1.0f,
+ -0.013f, 0.0f, -0.225f, 0.572f, 1.0f, -0.01f, 0.0f, -0.226f, 0.573f, 1.0f, -0.007f, 0.0f, -0.227f, 0.573f, 1.0f, -0.004f, 0.0f, -0.227f, 0.573f, 1.0f,
+ -0.001f, 0.0f, -0.227f, 0.574f, 1.0f, 0.002f, 0.0f, -0.227f, 0.575f, 1.0f, 0.005f, 0.0f, -0.227f, 0.576f, 1.0f, 0.008f, 0.0f, -0.226f, 0.577f, 1.0f,
+ 0.011f, 0.0f, -0.225f, 0.578f, 1.0f, 0.015f, 0.0f, -0.224f, 0.579f, 1.0f, 0.018f, 0.0f, -0.222f, 0.58f, 1.0f, 0.021f, 0.0f, -0.221f, 0.581f, 1.0f,
+ 0.024f, 0.0f, -0.219f, 0.582f, 1.0f, 0.027f, 0.0f, -0.217f, 0.582f, 1.0f, 0.03f, 0.0f, -0.215f, 0.583f, 1.0f, 0.033f, 0.0f, -0.213f, 0.583f, 1.0f,
+ 0.036f, 0.0f, -0.212f, 0.583f, 1.0f, 0.039f, 0.0f, -0.21f, 0.583f, 1.0f, 0.042f, 0.0f, -0.208f, 0.583f, 1.0f, 0.045f, 0.0f, -0.207f, 0.583f, 1.0f,
+ 0.048f, 0.0f, -0.205f, 0.583f, 1.0f, 0.051f, 0.0f, -0.204f, 0.583f, 1.0f, 0.054f, 0.0f, -0.203f, 0.583f, 1.0f, 0.058f, 0.0f, -0.203f, 0.583f, 1.0f,
+ 0.061f, 0.0f, -0.202f, 0.583f, 1.0f, 0.064f, 0.0f, -0.202f, 0.574f, 1.0f, 0.067f, 0.0f, -0.202f, 0.565f, 1.0f, 0.07f, 0.0f, -0.203f, 0.556f, 1.0f,
+ 0.073f, 0.0f, -0.203f, 0.547f, 1.0f, 0.075f, 0.0f, -0.204f, 0.515f, 1.0f, 0.078f, 0.0f, -0.204f, 0.483f, 1.0f, 0.08f, 0.0f, -0.205f, 0.451f, 1.0f,
+ 0.083f, 0.0f, -0.206f, 0.419f, 1.0f, 0.085f, 0.0f, -0.207f, 0.314f, 1.0f, 0.087f, 0.0f, -0.208f, 0.21f, 1.0f, 0.089f, 0.0f, -0.209f, 0.105f, 1.0f,
+ 0.091f, 0.0f, -0.21f, 0.0f, 1.0f,
+};
+
+static const float data28[257 * GP_PRIM_DATABUF_SIZE] = {
+ -0.637f, 0.0f, -0.172f, 0.0f, 1.0f, -0.641f, 0.0f, -0.172f, 0.0f, 1.0f, -0.643f, 0.0f, -0.172f, 0.0f, 1.0f, -0.646f, 0.0f, -0.172f, 0.0f, 1.0f,
+ -0.65f, 0.0f, -0.172f, 0.0f, 1.0f, -0.653f, 0.0f, -0.172f, 0.0f, 1.0f, -0.657f, 0.0f, -0.172f, 0.0f, 1.0f, -0.66f, 0.0f, -0.172f, 0.0f, 1.0f,
+ -0.664f, 0.0f, -0.171f, 0.0f, 1.0f, -0.668f, 0.0f, -0.171f, 0.0f, 1.0f, -0.672f, 0.0f, -0.171f, 0.0f, 1.0f, -0.677f, 0.0f, -0.171f, 0.0f, 1.0f,
+ -0.681f, 0.0f, -0.171f, 0.0f, 1.0f, -0.685f, 0.0f, -0.171f, 0.0f, 1.0f, -0.69f, 0.0f, -0.17f, 0.0f, 1.0f, -0.694f, 0.0f, -0.17f, 0.0f, 1.0f,
+ -0.699f, 0.0f, -0.17f, 0.0f, 1.0f, -0.704f, 0.0f, -0.169f, 0.0f, 1.0f, -0.708f, 0.0f, -0.169f, 0.0f, 1.0f, -0.713f, 0.0f, -0.168f, 0.0f, 1.0f,
+ -0.717f, 0.0f, -0.168f, 0.0f, 1.0f, -0.722f, 0.0f, -0.167f, 0.0f, 1.0f, -0.727f, 0.0f, -0.167f, 0.0f, 1.0f, -0.731f, 0.0f, -0.166f, 0.0f, 1.0f,
+ -0.735f, 0.0f, -0.166f, 0.0f, 1.0f, -0.74f, 0.0f, -0.165f, 0.0f, 1.0f, -0.744f, 0.0f, -0.164f, 0.0f, 1.0f, -0.749f, 0.0f, -0.163f, 0.0f, 1.0f,
+ -0.753f, 0.0f, -0.163f, 0.0f, 1.0f, -0.757f, 0.0f, -0.162f, 0.0f, 1.0f, -0.761f, 0.0f, -0.161f, 0.0f, 1.0f, -0.765f, 0.0f, -0.16f, 0.0f, 1.0f,
+ -0.769f, 0.0f, -0.159f, 0.0f, 1.0f, -0.773f, 0.0f, -0.158f, 0.0f, 1.0f, -0.777f, 0.0f, -0.157f, 0.0f, 1.0f, -0.781f, 0.0f, -0.156f, 0.001f, 1.0f,
+ -0.785f, 0.0f, -0.155f, 0.001f, 1.0f, -0.789f, 0.0f, -0.154f, 0.002f, 1.0f, -0.793f, 0.0f, -0.153f, 0.003f, 1.0f, -0.797f, 0.0f, -0.152f, 0.004f, 1.0f,
+ -0.801f, 0.0f, -0.15f, 0.005f, 1.0f, -0.805f, 0.0f, -0.149f, 0.006f, 1.0f, -0.81f, 0.0f, -0.147f, 0.008f, 1.0f, -0.814f, 0.0f, -0.146f, 0.009f, 1.0f,
+ -0.818f, 0.0f, -0.144f, 0.011f, 1.0f, -0.823f, 0.0f, -0.143f, 0.014f, 1.0f, -0.827f, 0.0f, -0.141f, 0.016f, 1.0f, -0.831f, 0.0f, -0.139f, 0.019f, 1.0f,
+ -0.836f, 0.0f, -0.138f, 0.022f, 1.0f, -0.84f, 0.0f, -0.136f, 0.024f, 1.0f, -0.844f, 0.0f, -0.135f, 0.026f, 1.0f, -0.849f, 0.0f, -0.133f, 0.027f, 1.0f,
+ -0.853f, 0.0f, -0.131f, 0.027f, 1.0f, -0.857f, 0.0f, -0.13f, 0.027f, 1.0f, -0.861f, 0.0f, -0.128f, 0.027f, 1.0f, -0.865f, 0.0f, -0.126f, 0.027f, 1.0f,
+ -0.868f, 0.0f, -0.125f, 0.026f, 1.0f, -0.872f, 0.0f, -0.123f, 0.025f, 1.0f, -0.876f, 0.0f, -0.121f, 0.025f, 1.0f, -0.879f, 0.0f, -0.119f, 0.024f, 1.0f,
+ -0.883f, 0.0f, -0.118f, 0.023f, 1.0f, -0.886f, 0.0f, -0.116f, 0.022f, 1.0f, -0.89f, 0.0f, -0.114f, 0.022f, 1.0f, -0.894f, 0.0f, -0.112f, 0.021f, 1.0f,
+ -0.898f, 0.0f, -0.11f, 0.022f, 1.0f, -0.901f, 0.0f, -0.107f, 0.022f, 1.0f, -0.905f, 0.0f, -0.105f, 0.024f, 1.0f, -0.909f, 0.0f, -0.103f, 0.026f, 1.0f,
+ -0.913f, 0.0f, -0.1f, 0.029f, 1.0f, -0.917f, 0.0f, -0.098f, 0.032f, 1.0f, -0.921f, 0.0f, -0.095f, 0.035f, 1.0f, -0.926f, 0.0f, -0.092f, 0.039f, 1.0f,
+ -0.93f, 0.0f, -0.09f, 0.043f, 1.0f, -0.934f, 0.0f, -0.087f, 0.047f, 1.0f, -0.938f, 0.0f, -0.084f, 0.051f, 1.0f, -0.942f, 0.0f, -0.081f, 0.055f, 1.0f,
+ -0.946f, 0.0f, -0.078f, 0.06f, 1.0f, -0.95f, 0.0f, -0.075f, 0.065f, 1.0f, -0.954f, 0.0f, -0.073f, 0.07f, 1.0f, -0.958f, 0.0f, -0.07f, 0.075f, 1.0f,
+ -0.961f, 0.0f, -0.067f, 0.081f, 1.0f, -0.965f, 0.0f, -0.064f, 0.087f, 1.0f, -0.968f, 0.0f, -0.061f, 0.092f, 1.0f, -0.972f, 0.0f, -0.058f, 0.098f, 1.0f,
+ -0.975f, 0.0f, -0.055f, 0.103f, 1.0f, -0.979f, 0.0f, -0.053f, 0.108f, 1.0f, -0.982f, 0.0f, -0.05f, 0.112f, 1.0f, -0.985f, 0.0f, -0.047f, 0.116f, 1.0f,
+ -0.988f, 0.0f, -0.045f, 0.12f, 1.0f, -0.991f, 0.0f, -0.042f, 0.123f, 1.0f, -0.994f, 0.0f, -0.039f, 0.126f, 1.0f, -0.997f, 0.0f, -0.037f, 0.129f, 1.0f,
+ -1.0f, 0.0f, -0.034f, 0.131f, 1.0f, -1.003f, 0.0f, -0.031f, 0.133f, 1.0f, -1.005f, 0.0f, -0.029f, 0.135f, 1.0f, -1.008f, 0.0f, -0.026f, 0.137f, 1.0f,
+ -1.01f, 0.0f, -0.024f, 0.139f, 1.0f, -1.013f, 0.0f, -0.021f, 0.141f, 1.0f, -1.016f, 0.0f, -0.018f, 0.143f, 1.0f, -1.018f, 0.0f, -0.016f, 0.144f, 1.0f,
+ -1.02f, 0.0f, -0.013f, 0.146f, 1.0f, -1.023f, 0.0f, -0.011f, 0.148f, 1.0f, -1.025f, 0.0f, -0.008f, 0.149f, 1.0f, -1.027f, 0.0f, -0.006f, 0.151f, 1.0f,
+ -1.029f, 0.0f, -0.003f, 0.152f, 1.0f, -1.032f, 0.0f, -0.001f, 0.154f, 1.0f, -1.034f, 0.0f, 0.001f, 0.154f, 1.0f, -1.036f, 0.0f, 0.004f, 0.155f, 1.0f,
+ -1.038f, 0.0f, 0.006f, 0.156f, 1.0f, -1.041f, 0.0f, 0.008f, 0.156f, 1.0f, -1.043f, 0.0f, 0.01f, 0.157f, 1.0f, -1.045f, 0.0f, 0.013f, 0.157f, 1.0f,
+ -1.047f, 0.0f, 0.015f, 0.157f, 1.0f, -1.049f, 0.0f, 0.018f, 0.158f, 1.0f, -1.051f, 0.0f, 0.02f, 0.158f, 1.0f, -1.053f, 0.0f, 0.023f, 0.158f, 1.0f,
+ -1.055f, 0.0f, 0.025f, 0.158f, 1.0f, -1.057f, 0.0f, 0.028f, 0.158f, 1.0f, -1.059f, 0.0f, 0.03f, 0.158f, 1.0f, -1.061f, 0.0f, 0.033f, 0.158f, 1.0f,
+ -1.063f, 0.0f, 0.036f, 0.158f, 1.0f, -1.065f, 0.0f, 0.038f, 0.158f, 1.0f, -1.067f, 0.0f, 0.041f, 0.158f, 1.0f, -1.069f, 0.0f, 0.044f, 0.157f, 1.0f,
+ -1.071f, 0.0f, 0.047f, 0.157f, 1.0f, -1.073f, 0.0f, 0.049f, 0.156f, 1.0f, -1.074f, 0.0f, 0.052f, 0.155f, 1.0f, -1.076f, 0.0f, 0.055f, 0.154f, 1.0f,
+ -1.078f, 0.0f, 0.058f, 0.153f, 1.0f, -1.08f, 0.0f, 0.061f, 0.152f, 1.0f, -1.082f, 0.0f, 0.064f, 0.15f, 1.0f, -1.083f, 0.0f, 0.067f, 0.148f, 1.0f,
+ -1.085f, 0.0f, 0.07f, 0.146f, 1.0f, -1.087f, 0.0f, 0.073f, 0.144f, 1.0f, -1.089f, 0.0f, 0.076f, 0.142f, 1.0f, -1.091f, 0.0f, 0.08f, 0.14f, 1.0f,
+ -1.092f, 0.0f, 0.083f, 0.138f, 1.0f, -1.094f, 0.0f, 0.086f, 0.136f, 1.0f, -1.096f, 0.0f, 0.09f, 0.135f, 1.0f, -1.097f, 0.0f, 0.093f, 0.134f, 1.0f,
+ -1.099f, 0.0f, 0.096f, 0.134f, 1.0f, -1.101f, 0.0f, 0.1f, 0.134f, 1.0f, -1.103f, 0.0f, 0.103f, 0.136f, 1.0f, -1.104f, 0.0f, 0.107f, 0.139f, 1.0f,
+ -1.106f, 0.0f, 0.111f, 0.144f, 1.0f, -1.107f, 0.0f, 0.114f, 0.15f, 1.0f, -1.109f, 0.0f, 0.118f, 0.158f, 1.0f, -1.11f, 0.0f, 0.122f, 0.167f, 1.0f,
+ -1.111f, 0.0f, 0.126f, 0.178f, 1.0f, -1.113f, 0.0f, 0.13f, 0.191f, 1.0f, -1.114f, 0.0f, 0.134f, 0.205f, 1.0f, -1.115f, 0.0f, 0.138f, 0.22f, 1.0f,
+ -1.116f, 0.0f, 0.142f, 0.237f, 1.0f, -1.117f, 0.0f, 0.146f, 0.254f, 1.0f, -1.118f, 0.0f, 0.15f, 0.272f, 1.0f, -1.119f, 0.0f, 0.155f, 0.291f, 1.0f,
+ -1.119f, 0.0f, 0.159f, 0.31f, 1.0f, -1.12f, 0.0f, 0.163f, 0.329f, 1.0f, -1.121f, 0.0f, 0.167f, 0.348f, 1.0f, -1.121f, 0.0f, 0.172f, 0.367f, 1.0f,
+ -1.122f, 0.0f, 0.176f, 0.386f, 1.0f, -1.122f, 0.0f, 0.18f, 0.405f, 1.0f, -1.123f, 0.0f, 0.184f, 0.423f, 1.0f, -1.123f, 0.0f, 0.189f, 0.441f, 1.0f,
+ -1.124f, 0.0f, 0.193f, 0.458f, 1.0f, -1.124f, 0.0f, 0.197f, 0.475f, 1.0f, -1.124f, 0.0f, 0.202f, 0.492f, 1.0f, -1.124f, 0.0f, 0.206f, 0.508f, 1.0f,
+ -1.125f, 0.0f, 0.21f, 0.524f, 1.0f, -1.125f, 0.0f, 0.214f, 0.539f, 1.0f, -1.125f, 0.0f, 0.218f, 0.554f, 1.0f, -1.124f, 0.0f, 0.223f, 0.568f, 1.0f,
+ -1.124f, 0.0f, 0.227f, 0.581f, 1.0f, -1.124f, 0.0f, 0.231f, 0.593f, 1.0f, -1.124f, 0.0f, 0.235f, 0.604f, 1.0f, -1.123f, 0.0f, 0.239f, 0.614f, 1.0f,
+ -1.123f, 0.0f, 0.243f, 0.624f, 1.0f, -1.122f, 0.0f, 0.247f, 0.632f, 1.0f, -1.122f, 0.0f, 0.251f, 0.64f, 1.0f, -1.121f, 0.0f, 0.255f, 0.646f, 1.0f,
+ -1.121f, 0.0f, 0.258f, 0.653f, 1.0f, -1.12f, 0.0f, 0.262f, 0.658f, 1.0f, -1.119f, 0.0f, 0.266f, 0.663f, 1.0f, -1.118f, 0.0f, 0.269f, 0.668f, 1.0f,
+ -1.117f, 0.0f, 0.272f, 0.673f, 1.0f, -1.117f, 0.0f, 0.276f, 0.678f, 1.0f, -1.116f, 0.0f, 0.279f, 0.682f, 1.0f, -1.115f, 0.0f, 0.282f, 0.687f, 1.0f,
+ -1.113f, 0.0f, 0.285f, 0.692f, 1.0f, -1.112f, 0.0f, 0.289f, 0.697f, 1.0f, -1.111f, 0.0f, 0.292f, 0.702f, 1.0f, -1.11f, 0.0f, 0.294f, 0.708f, 1.0f,
+ -1.109f, 0.0f, 0.297f, 0.713f, 1.0f, -1.108f, 0.0f, 0.3f, 0.718f, 1.0f, -1.106f, 0.0f, 0.303f, 0.724f, 1.0f, -1.105f, 0.0f, 0.306f, 0.73f, 1.0f,
+ -1.104f, 0.0f, 0.309f, 0.735f, 1.0f, -1.102f, 0.0f, 0.312f, 0.741f, 1.0f, -1.101f, 0.0f, 0.315f, 0.746f, 1.0f, -1.099f, 0.0f, 0.318f, 0.751f, 1.0f,
+ -1.098f, 0.0f, 0.321f, 0.756f, 1.0f, -1.096f, 0.0f, 0.323f, 0.761f, 1.0f, -1.094f, 0.0f, 0.326f, 0.766f, 1.0f, -1.093f, 0.0f, 0.329f, 0.771f, 1.0f,
+ -1.091f, 0.0f, 0.332f, 0.776f, 1.0f, -1.089f, 0.0f, 0.335f, 0.781f, 1.0f, -1.087f, 0.0f, 0.338f, 0.786f, 1.0f, -1.085f, 0.0f, 0.341f, 0.791f, 1.0f,
+ -1.082f, 0.0f, 0.344f, 0.797f, 1.0f, -1.08f, 0.0f, 0.347f, 0.802f, 1.0f, -1.078f, 0.0f, 0.349f, 0.808f, 1.0f, -1.075f, 0.0f, 0.352f, 0.814f, 1.0f,
+ -1.072f, 0.0f, 0.355f, 0.82f, 1.0f, -1.069f, 0.0f, 0.358f, 0.826f, 1.0f, -1.066f, 0.0f, 0.36f, 0.831f, 1.0f, -1.063f, 0.0f, 0.363f, 0.837f, 1.0f,
+ -1.059f, 0.0f, 0.366f, 0.842f, 1.0f, -1.055f, 0.0f, 0.368f, 0.847f, 1.0f, -1.051f, 0.0f, 0.371f, 0.851f, 1.0f, -1.047f, 0.0f, 0.373f, 0.856f, 1.0f,
+ -1.042f, 0.0f, 0.375f, 0.86f, 1.0f, -1.037f, 0.0f, 0.378f, 0.863f, 1.0f, -1.031f, 0.0f, 0.38f, 0.866f, 1.0f, -1.026f, 0.0f, 0.382f, 0.869f, 1.0f,
+ -1.02f, 0.0f, 0.384f, 0.871f, 1.0f, -1.014f, 0.0f, 0.386f, 0.873f, 1.0f, -1.007f, 0.0f, 0.387f, 0.875f, 1.0f, -1.0f, 0.0f, 0.389f, 0.876f, 1.0f,
+ -0.994f, 0.0f, 0.39f, 0.877f, 1.0f, -0.987f, 0.0f, 0.392f, 0.878f, 1.0f, -0.979f, 0.0f, 0.393f, 0.879f, 1.0f, -0.972f, 0.0f, 0.394f, 0.88f, 1.0f,
+ -0.964f, 0.0f, 0.395f, 0.881f, 1.0f, -0.956f, 0.0f, 0.395f, 0.881f, 1.0f, -0.948f, 0.0f, 0.395f, 0.882f, 1.0f, -0.94f, 0.0f, 0.395f, 0.882f, 1.0f,
+ -0.932f, 0.0f, 0.395f, 0.883f, 1.0f, -0.923f, 0.0f, 0.394f, 0.883f, 1.0f, -0.915f, 0.0f, 0.393f, 0.883f, 1.0f, -0.906f, 0.0f, 0.391f, 0.883f, 1.0f,
+ -0.896f, 0.0f, 0.389f, 0.881f, 1.0f, -0.887f, 0.0f, 0.386f, 0.876f, 1.0f, -0.877f, 0.0f, 0.382f, 0.866f, 1.0f, -0.867f, 0.0f, 0.378f, 0.85f, 1.0f,
+ -0.857f, 0.0f, 0.373f, 0.828f, 1.0f, -0.848f, 0.0f, 0.368f, 0.799f, 1.0f, -0.838f, 0.0f, 0.363f, 0.764f, 1.0f, -0.829f, 0.0f, 0.357f, 0.723f, 1.0f,
+ -0.819f, 0.0f, 0.352f, 0.679f, 1.0f, -0.811f, 0.0f, 0.347f, 0.631f, 1.0f, -0.802f, 0.0f, 0.342f, 0.579f, 1.0f, -0.794f, 0.0f, 0.338f, 0.525f, 1.0f,
+ -0.786f, 0.0f, 0.333f, 0.469f, 1.0f, -0.779f, 0.0f, 0.329f, 0.412f, 1.0f, -0.772f, 0.0f, 0.325f, 0.351f, 1.0f, -0.766f, 0.0f, 0.321f, 0.3f, 1.0f,
+ -0.757f, 0.0f, 0.317f, 0.219f, 1.0f,
+};
+
+static const float data29[205 * GP_PRIM_DATABUF_SIZE] = {
+ 0.816f, 0.0f, 0.326f, 0.285f, 1.0f, 0.819f, 0.0f, 0.328f, 0.287f, 1.0f, 0.821f, 0.0f, 0.33f, 0.29f, 1.0f, 0.823f, 0.0f, 0.331f, 0.295f, 1.0f,
+ 0.825f, 0.0f, 0.333f, 0.304f, 1.0f, 0.828f, 0.0f, 0.335f, 0.315f, 1.0f, 0.83f, 0.0f, 0.337f, 0.328f, 1.0f, 0.833f, 0.0f, 0.339f, 0.341f, 1.0f,
+ 0.836f, 0.0f, 0.341f, 0.355f, 1.0f, 0.839f, 0.0f, 0.343f, 0.368f, 1.0f, 0.842f, 0.0f, 0.345f, 0.38f, 1.0f, 0.845f, 0.0f, 0.347f, 0.392f, 1.0f,
+ 0.848f, 0.0f, 0.349f, 0.402f, 1.0f, 0.851f, 0.0f, 0.351f, 0.412f, 1.0f, 0.854f, 0.0f, 0.352f, 0.421f, 1.0f, 0.857f, 0.0f, 0.354f, 0.429f, 1.0f,
+ 0.861f, 0.0f, 0.356f, 0.437f, 1.0f, 0.865f, 0.0f, 0.357f, 0.444f, 1.0f, 0.869f, 0.0f, 0.359f, 0.452f, 1.0f, 0.872f, 0.0f, 0.36f, 0.46f, 1.0f,
+ 0.876f, 0.0f, 0.361f, 0.47f, 1.0f, 0.881f, 0.0f, 0.363f, 0.481f, 1.0f, 0.885f, 0.0f, 0.364f, 0.491f, 1.0f, 0.889f, 0.0f, 0.365f, 0.501f, 1.0f,
+ 0.893f, 0.0f, 0.366f, 0.511f, 1.0f, 0.898f, 0.0f, 0.367f, 0.52f, 1.0f, 0.902f, 0.0f, 0.368f, 0.528f, 1.0f, 0.906f, 0.0f, 0.37f, 0.535f, 1.0f,
+ 0.911f, 0.0f, 0.371f, 0.542f, 1.0f, 0.915f, 0.0f, 0.372f, 0.548f, 1.0f, 0.92f, 0.0f, 0.373f, 0.554f, 1.0f, 0.924f, 0.0f, 0.374f, 0.559f, 1.0f,
+ 0.929f, 0.0f, 0.375f, 0.564f, 1.0f, 0.933f, 0.0f, 0.376f, 0.567f, 1.0f, 0.938f, 0.0f, 0.377f, 0.57f, 1.0f, 0.943f, 0.0f, 0.378f, 0.572f, 1.0f,
+ 0.947f, 0.0f, 0.378f, 0.574f, 1.0f, 0.952f, 0.0f, 0.379f, 0.576f, 1.0f, 0.956f, 0.0f, 0.38f, 0.577f, 1.0f, 0.961f, 0.0f, 0.38f, 0.579f, 1.0f,
+ 0.966f, 0.0f, 0.381f, 0.581f, 1.0f, 0.971f, 0.0f, 0.381f, 0.585f, 1.0f, 0.975f, 0.0f, 0.382f, 0.588f, 1.0f, 0.98f, 0.0f, 0.382f, 0.591f, 1.0f,
+ 0.985f, 0.0f, 0.382f, 0.595f, 1.0f, 0.989f, 0.0f, 0.382f, 0.597f, 1.0f, 0.994f, 0.0f, 0.382f, 0.6f, 1.0f, 0.999f, 0.0f, 0.382f, 0.603f, 1.0f,
+ 1.003f, 0.0f, 0.382f, 0.605f, 1.0f, 1.008f, 0.0f, 0.381f, 0.607f, 1.0f, 1.013f, 0.0f, 0.381f, 0.61f, 1.0f, 1.017f, 0.0f, 0.381f, 0.611f, 1.0f,
+ 1.021f, 0.0f, 0.381f, 0.613f, 1.0f, 1.025f, 0.0f, 0.38f, 0.613f, 1.0f, 1.029f, 0.0f, 0.38f, 0.614f, 1.0f, 1.033f, 0.0f, 0.379f, 0.614f, 1.0f,
+ 1.037f, 0.0f, 0.379f, 0.614f, 1.0f, 1.041f, 0.0f, 0.378f, 0.614f, 1.0f, 1.044f, 0.0f, 0.378f, 0.614f, 1.0f, 1.048f, 0.0f, 0.377f, 0.614f, 1.0f,
+ 1.051f, 0.0f, 0.376f, 0.613f, 1.0f, 1.054f, 0.0f, 0.375f, 0.612f, 1.0f, 1.057f, 0.0f, 0.374f, 0.611f, 1.0f, 1.06f, 0.0f, 0.373f, 0.61f, 1.0f,
+ 1.063f, 0.0f, 0.372f, 0.609f, 1.0f, 1.066f, 0.0f, 0.371f, 0.609f, 1.0f, 1.068f, 0.0f, 0.37f, 0.608f, 1.0f, 1.071f, 0.0f, 0.368f, 0.608f, 1.0f,
+ 1.073f, 0.0f, 0.367f, 0.608f, 1.0f, 1.076f, 0.0f, 0.365f, 0.608f, 1.0f, 1.078f, 0.0f, 0.364f, 0.607f, 1.0f, 1.081f, 0.0f, 0.362f, 0.607f, 1.0f,
+ 1.083f, 0.0f, 0.36f, 0.607f, 1.0f, 1.085f, 0.0f, 0.358f, 0.606f, 1.0f, 1.087f, 0.0f, 0.356f, 0.606f, 1.0f, 1.09f, 0.0f, 0.354f, 0.606f, 1.0f,
+ 1.092f, 0.0f, 0.352f, 0.606f, 1.0f, 1.094f, 0.0f, 0.35f, 0.606f, 1.0f, 1.096f, 0.0f, 0.348f, 0.606f, 1.0f, 1.097f, 0.0f, 0.346f, 0.606f, 1.0f,
+ 1.099f, 0.0f, 0.344f, 0.606f, 1.0f, 1.101f, 0.0f, 0.341f, 0.606f, 1.0f, 1.103f, 0.0f, 0.339f, 0.606f, 1.0f, 1.104f, 0.0f, 0.337f, 0.607f, 1.0f,
+ 1.106f, 0.0f, 0.335f, 0.607f, 1.0f, 1.108f, 0.0f, 0.332f, 0.607f, 1.0f, 1.109f, 0.0f, 0.33f, 0.608f, 1.0f, 1.111f, 0.0f, 0.327f, 0.608f, 1.0f,
+ 1.113f, 0.0f, 0.324f, 0.608f, 1.0f, 1.114f, 0.0f, 0.322f, 0.609f, 1.0f, 1.116f, 0.0f, 0.319f, 0.609f, 1.0f, 1.117f, 0.0f, 0.316f, 0.609f, 1.0f,
+ 1.118f, 0.0f, 0.313f, 0.609f, 1.0f, 1.12f, 0.0f, 0.31f, 0.609f, 1.0f, 1.121f, 0.0f, 0.307f, 0.609f, 1.0f, 1.123f, 0.0f, 0.304f, 0.608f, 1.0f,
+ 1.124f, 0.0f, 0.301f, 0.608f, 1.0f, 1.125f, 0.0f, 0.297f, 0.607f, 1.0f, 1.126f, 0.0f, 0.294f, 0.606f, 1.0f, 1.127f, 0.0f, 0.29f, 0.605f, 1.0f,
+ 1.129f, 0.0f, 0.287f, 0.603f, 1.0f, 1.13f, 0.0f, 0.283f, 0.601f, 1.0f, 1.131f, 0.0f, 0.279f, 0.599f, 1.0f, 1.132f, 0.0f, 0.276f, 0.597f, 1.0f,
+ 1.132f, 0.0f, 0.272f, 0.595f, 1.0f, 1.133f, 0.0f, 0.268f, 0.593f, 1.0f, 1.134f, 0.0f, 0.264f, 0.592f, 1.0f, 1.135f, 0.0f, 0.26f, 0.591f, 1.0f,
+ 1.135f, 0.0f, 0.256f, 0.59f, 1.0f, 1.136f, 0.0f, 0.252f, 0.589f, 1.0f, 1.136f, 0.0f, 0.248f, 0.588f, 1.0f, 1.137f, 0.0f, 0.244f, 0.587f, 1.0f,
+ 1.137f, 0.0f, 0.24f, 0.586f, 1.0f, 1.138f, 0.0f, 0.236f, 0.585f, 1.0f, 1.138f, 0.0f, 0.232f, 0.584f, 1.0f, 1.138f, 0.0f, 0.228f, 0.582f, 1.0f,
+ 1.138f, 0.0f, 0.224f, 0.581f, 1.0f, 1.138f, 0.0f, 0.22f, 0.579f, 1.0f, 1.138f, 0.0f, 0.216f, 0.578f, 1.0f, 1.138f, 0.0f, 0.212f, 0.576f, 1.0f,
+ 1.138f, 0.0f, 0.208f, 0.575f, 1.0f, 1.138f, 0.0f, 0.204f, 0.573f, 1.0f, 1.137f, 0.0f, 0.2f, 0.572f, 1.0f, 1.137f, 0.0f, 0.196f, 0.571f, 1.0f,
+ 1.137f, 0.0f, 0.192f, 0.569f, 1.0f, 1.136f, 0.0f, 0.188f, 0.568f, 1.0f, 1.136f, 0.0f, 0.184f, 0.567f, 1.0f, 1.135f, 0.0f, 0.18f, 0.566f, 1.0f,
+ 1.134f, 0.0f, 0.176f, 0.565f, 1.0f, 1.133f, 0.0f, 0.172f, 0.563f, 1.0f, 1.132f, 0.0f, 0.168f, 0.561f, 1.0f, 1.131f, 0.0f, 0.164f, 0.559f, 1.0f,
+ 1.13f, 0.0f, 0.16f, 0.556f, 1.0f, 1.129f, 0.0f, 0.156f, 0.552f, 1.0f, 1.128f, 0.0f, 0.152f, 0.548f, 1.0f, 1.127f, 0.0f, 0.148f, 0.543f, 1.0f,
+ 1.126f, 0.0f, 0.144f, 0.537f, 1.0f, 1.124f, 0.0f, 0.14f, 0.53f, 1.0f, 1.123f, 0.0f, 0.136f, 0.522f, 1.0f, 1.122f, 0.0f, 0.132f, 0.514f, 1.0f,
+ 1.12f, 0.0f, 0.128f, 0.505f, 1.0f, 1.118f, 0.0f, 0.123f, 0.495f, 1.0f, 1.117f, 0.0f, 0.119f, 0.486f, 1.0f, 1.115f, 0.0f, 0.115f, 0.476f, 1.0f,
+ 1.113f, 0.0f, 0.111f, 0.466f, 1.0f, 1.111f, 0.0f, 0.107f, 0.456f, 1.0f, 1.11f, 0.0f, 0.102f, 0.446f, 1.0f, 1.108f, 0.0f, 0.098f, 0.436f, 1.0f,
+ 1.105f, 0.0f, 0.094f, 0.425f, 1.0f, 1.103f, 0.0f, 0.09f, 0.414f, 1.0f, 1.101f, 0.0f, 0.085f, 0.402f, 1.0f, 1.099f, 0.0f, 0.081f, 0.389f, 1.0f,
+ 1.096f, 0.0f, 0.077f, 0.377f, 1.0f, 1.094f, 0.0f, 0.072f, 0.364f, 1.0f, 1.091f, 0.0f, 0.068f, 0.351f, 1.0f, 1.088f, 0.0f, 0.063f, 0.338f, 1.0f,
+ 1.085f, 0.0f, 0.059f, 0.325f, 1.0f, 1.082f, 0.0f, 0.054f, 0.313f, 1.0f, 1.079f, 0.0f, 0.05f, 0.301f, 1.0f, 1.075f, 0.0f, 0.045f, 0.29f, 1.0f,
+ 1.071f, 0.0f, 0.04f, 0.281f, 1.0f, 1.067f, 0.0f, 0.035f, 0.272f, 1.0f, 1.063f, 0.0f, 0.031f, 0.266f, 1.0f, 1.059f, 0.0f, 0.026f, 0.261f, 1.0f,
+ 1.054f, 0.0f, 0.021f, 0.258f, 1.0f, 1.049f, 0.0f, 0.016f, 0.257f, 1.0f, 1.043f, 0.0f, 0.011f, 0.259f, 1.0f, 1.037f, 0.0f, 0.006f, 0.264f, 1.0f,
+ 1.031f, 0.0f, 0.0f, 0.272f, 1.0f, 1.025f, 0.0f, -0.005f, 0.283f, 1.0f, 1.018f, 0.0f, -0.01f, 0.296f, 1.0f, 1.011f, 0.0f, -0.015f, 0.313f, 1.0f,
+ 1.003f, 0.0f, -0.021f, 0.33f, 1.0f, 0.996f, 0.0f, -0.026f, 0.348f, 1.0f, 0.988f, 0.0f, -0.032f, 0.365f, 1.0f, 0.979f, 0.0f, -0.038f, 0.379f, 1.0f,
+ 0.971f, 0.0f, -0.044f, 0.389f, 1.0f, 0.962f, 0.0f, -0.05f, 0.394f, 1.0f, 0.953f, 0.0f, -0.057f, 0.392f, 1.0f, 0.944f, 0.0f, -0.063f, 0.384f, 1.0f,
+ 0.934f, 0.0f, -0.069f, 0.368f, 1.0f, 0.924f, 0.0f, -0.075f, 0.347f, 1.0f, 0.914f, 0.0f, -0.081f, 0.32f, 1.0f, 0.903f, 0.0f, -0.087f, 0.289f, 1.0f,
+ 0.893f, 0.0f, -0.092f, 0.256f, 1.0f, 0.882f, 0.0f, -0.098f, 0.223f, 1.0f, 0.871f, 0.0f, -0.103f, 0.191f, 1.0f, 0.86f, 0.0f, -0.108f, 0.162f, 1.0f,
+ 0.849f, 0.0f, -0.112f, 0.136f, 1.0f, 0.838f, 0.0f, -0.117f, 0.112f, 1.0f, 0.827f, 0.0f, -0.121f, 0.091f, 1.0f, 0.815f, 0.0f, -0.125f, 0.074f, 1.0f,
+ 0.804f, 0.0f, -0.128f, 0.059f, 1.0f, 0.793f, 0.0f, -0.132f, 0.046f, 1.0f, 0.782f, 0.0f, -0.135f, 0.036f, 1.0f, 0.771f, 0.0f, -0.138f, 0.028f, 1.0f,
+ 0.76f, 0.0f, -0.141f, 0.021f, 1.0f, 0.749f, 0.0f, -0.144f, 0.016f, 1.0f, 0.738f, 0.0f, -0.147f, 0.012f, 1.0f, 0.728f, 0.0f, -0.149f, 0.009f, 1.0f,
+ 0.718f, 0.0f, -0.152f, 0.006f, 1.0f, 0.708f, 0.0f, -0.154f, 0.004f, 1.0f, 0.699f, 0.0f, -0.157f, 0.003f, 1.0f, 0.691f, 0.0f, -0.159f, 0.002f, 1.0f,
+ 0.68f, 0.0f, -0.162f, 0.0f, 1.0f,
+};
+
+static const float data30[33 * GP_PRIM_DATABUF_SIZE] = {
+ -1.02f, 0.0f, 0.179f, 0.21f, 1.0f, -1.014f, 0.0f, 0.182f, 0.301f, 1.0f, -1.01f, 0.0f, 0.184f, 0.36f, 1.0f, -1.004f, 0.0f, 0.186f, 0.426f, 1.0f,
+ -0.999f, 0.0f, 0.188f, 0.479f, 1.0f, -0.993f, 0.0f, 0.19f, 0.519f, 1.0f, -0.987f, 0.0f, 0.191f, 0.545f, 1.0f, -0.981f, 0.0f, 0.192f, 0.562f, 1.0f,
+ -0.975f, 0.0f, 0.193f, 0.575f, 1.0f, -0.968f, 0.0f, 0.193f, 0.582f, 1.0f, -0.961f, 0.0f, 0.193f, 0.587f, 1.0f, -0.954f, 0.0f, 0.191f, 0.592f, 1.0f,
+ -0.946f, 0.0f, 0.19f, 0.597f, 1.0f, -0.938f, 0.0f, 0.187f, 0.6f, 1.0f, -0.93f, 0.0f, 0.183f, 0.603f, 1.0f, -0.922f, 0.0f, 0.178f, 0.606f, 1.0f,
+ -0.913f, 0.0f, 0.173f, 0.608f, 1.0f, -0.905f, 0.0f, 0.168f, 0.61f, 1.0f, -0.898f, 0.0f, 0.162f, 0.612f, 1.0f, -0.89f, 0.0f, 0.156f, 0.613f, 1.0f,
+ -0.883f, 0.0f, 0.15f, 0.612f, 1.0f, -0.877f, 0.0f, 0.143f, 0.608f, 1.0f, -0.871f, 0.0f, 0.137f, 0.602f, 1.0f, -0.865f, 0.0f, 0.131f, 0.593f, 1.0f,
+ -0.86f, 0.0f, 0.125f, 0.577f, 1.0f, -0.855f, 0.0f, 0.12f, 0.554f, 1.0f, -0.85f, 0.0f, 0.114f, 0.524f, 1.0f, -0.846f, 0.0f, 0.109f, 0.487f, 1.0f,
+ -0.842f, 0.0f, 0.104f, 0.443f, 1.0f, -0.838f, 0.0f, 0.1f, 0.394f, 1.0f, -0.835f, 0.0f, 0.095f, 0.339f, 1.0f, -0.832f, 0.0f, 0.091f, 0.295f, 1.0f,
+ -0.828f, 0.0f, 0.086f, 0.227f, 1.0f,
+};
+
+static const float data31[37 * GP_PRIM_DATABUF_SIZE] = {
+ 0.777f, 0.0f, 0.096f, 0.278f, 1.0f, 0.779f, 0.0f, 0.1f, 0.307f, 1.0f, 0.781f, 0.0f, 0.103f, 0.326f, 1.0f, 0.782f, 0.0f, 0.106f, 0.349f, 1.0f,
+ 0.784f, 0.0f, 0.109f, 0.372f, 1.0f, 0.786f, 0.0f, 0.112f, 0.395f, 1.0f, 0.789f, 0.0f, 0.116f, 0.418f, 1.0f, 0.791f, 0.0f, 0.119f, 0.44f, 1.0f,
+ 0.794f, 0.0f, 0.123f, 0.462f, 1.0f, 0.798f, 0.0f, 0.127f, 0.484f, 1.0f, 0.801f, 0.0f, 0.13f, 0.504f, 1.0f, 0.806f, 0.0f, 0.134f, 0.522f, 1.0f,
+ 0.81f, 0.0f, 0.138f, 0.54f, 1.0f, 0.815f, 0.0f, 0.142f, 0.556f, 1.0f, 0.82f, 0.0f, 0.146f, 0.571f, 1.0f, 0.826f, 0.0f, 0.15f, 0.584f, 1.0f,
+ 0.832f, 0.0f, 0.154f, 0.596f, 1.0f, 0.839f, 0.0f, 0.159f, 0.607f, 1.0f, 0.846f, 0.0f, 0.163f, 0.616f, 1.0f, 0.854f, 0.0f, 0.166f, 0.623f, 1.0f,
+ 0.862f, 0.0f, 0.17f, 0.628f, 1.0f, 0.87f, 0.0f, 0.174f, 0.632f, 1.0f, 0.878f, 0.0f, 0.177f, 0.632f, 1.0f, 0.887f, 0.0f, 0.18f, 0.63f, 1.0f,
+ 0.895f, 0.0f, 0.183f, 0.623f, 1.0f, 0.903f, 0.0f, 0.186f, 0.611f, 1.0f, 0.912f, 0.0f, 0.188f, 0.592f, 1.0f, 0.92f, 0.0f, 0.19f, 0.567f, 1.0f,
+ 0.928f, 0.0f, 0.192f, 0.533f, 1.0f, 0.935f, 0.0f, 0.193f, 0.492f, 1.0f, 0.943f, 0.0f, 0.194f, 0.442f, 1.0f, 0.95f, 0.0f, 0.196f, 0.385f, 1.0f,
+ 0.957f, 0.0f, 0.197f, 0.321f, 1.0f, 0.963f, 0.0f, 0.197f, 0.253f, 1.0f, 0.97f, 0.0f, 0.198f, 0.175f, 1.0f, 0.975f, 0.0f, 0.199f, 0.107f, 1.0f,
+ 0.983f, 0.0f, 0.199f, 0.0f, 1.0f,
+};
+
+static const float data32[201 * GP_PRIM_DATABUF_SIZE] = {
+ -0.437f, 0.0f, 0.508f, 0.0f, 1.0f, -0.435f, 0.0f, 0.51f, 0.0f, 1.0f, -0.434f, 0.0f, 0.511f, 0.0f, 1.0f, -0.432f, 0.0f, 0.512f, 0.0f, 1.0f,
+ -0.43f, 0.0f, 0.513f, 0.0f, 1.0f, -0.428f, 0.0f, 0.514f, 0.001f, 1.0f, -0.426f, 0.0f, 0.515f, 0.002f, 1.0f, -0.424f, 0.0f, 0.517f, 0.004f, 1.0f,
+ -0.422f, 0.0f, 0.518f, 0.007f, 1.0f, -0.42f, 0.0f, 0.519f, 0.012f, 1.0f, -0.418f, 0.0f, 0.521f, 0.018f, 1.0f, -0.416f, 0.0f, 0.522f, 0.025f, 1.0f,
+ -0.414f, 0.0f, 0.523f, 0.034f, 1.0f, -0.411f, 0.0f, 0.525f, 0.043f, 1.0f, -0.409f, 0.0f, 0.526f, 0.053f, 1.0f, -0.407f, 0.0f, 0.528f, 0.063f, 1.0f,
+ -0.404f, 0.0f, 0.529f, 0.073f, 1.0f, -0.402f, 0.0f, 0.531f, 0.083f, 1.0f, -0.399f, 0.0f, 0.532f, 0.092f, 1.0f, -0.396f, 0.0f, 0.534f, 0.101f, 1.0f,
+ -0.394f, 0.0f, 0.535f, 0.11f, 1.0f, -0.391f, 0.0f, 0.536f, 0.118f, 1.0f, -0.388f, 0.0f, 0.538f, 0.126f, 1.0f, -0.386f, 0.0f, 0.539f, 0.133f, 1.0f,
+ -0.383f, 0.0f, 0.54f, 0.14f, 1.0f, -0.38f, 0.0f, 0.542f, 0.147f, 1.0f, -0.377f, 0.0f, 0.543f, 0.153f, 1.0f, -0.374f, 0.0f, 0.544f, 0.159f, 1.0f,
+ -0.37f, 0.0f, 0.545f, 0.166f, 1.0f, -0.367f, 0.0f, 0.546f, 0.172f, 1.0f, -0.364f, 0.0f, 0.547f, 0.179f, 1.0f, -0.361f, 0.0f, 0.548f, 0.186f, 1.0f,
+ -0.357f, 0.0f, 0.549f, 0.193f, 1.0f, -0.354f, 0.0f, 0.55f, 0.202f, 1.0f, -0.35f, 0.0f, 0.551f, 0.211f, 1.0f, -0.347f, 0.0f, 0.552f, 0.221f, 1.0f,
+ -0.343f, 0.0f, 0.552f, 0.233f, 1.0f, -0.339f, 0.0f, 0.553f, 0.245f, 1.0f, -0.336f, 0.0f, 0.553f, 0.258f, 1.0f, -0.332f, 0.0f, 0.554f, 0.272f, 1.0f,
+ -0.328f, 0.0f, 0.554f, 0.286f, 1.0f, -0.324f, 0.0f, 0.554f, 0.301f, 1.0f, -0.321f, 0.0f, 0.555f, 0.317f, 1.0f, -0.317f, 0.0f, 0.555f, 0.332f, 1.0f,
+ -0.313f, 0.0f, 0.555f, 0.348f, 1.0f, -0.309f, 0.0f, 0.555f, 0.364f, 1.0f, -0.305f, 0.0f, 0.555f, 0.38f, 1.0f, -0.302f, 0.0f, 0.555f, 0.396f, 1.0f,
+ -0.298f, 0.0f, 0.555f, 0.411f, 1.0f, -0.294f, 0.0f, 0.555f, 0.426f, 1.0f, -0.29f, 0.0f, 0.554f, 0.44f, 1.0f, -0.287f, 0.0f, 0.554f, 0.454f, 1.0f,
+ -0.283f, 0.0f, 0.554f, 0.467f, 1.0f, -0.28f, 0.0f, 0.553f, 0.479f, 1.0f, -0.276f, 0.0f, 0.553f, 0.49f, 1.0f, -0.273f, 0.0f, 0.552f, 0.5f, 1.0f,
+ -0.269f, 0.0f, 0.552f, 0.51f, 1.0f, -0.266f, 0.0f, 0.551f, 0.519f, 1.0f, -0.263f, 0.0f, 0.55f, 0.527f, 1.0f, -0.26f, 0.0f, 0.549f, 0.534f, 1.0f,
+ -0.256f, 0.0f, 0.549f, 0.541f, 1.0f, -0.253f, 0.0f, 0.548f, 0.547f, 1.0f, -0.25f, 0.0f, 0.547f, 0.552f, 1.0f, -0.247f, 0.0f, 0.546f, 0.557f, 1.0f,
+ -0.244f, 0.0f, 0.545f, 0.561f, 1.0f, -0.241f, 0.0f, 0.544f, 0.564f, 1.0f, -0.238f, 0.0f, 0.543f, 0.567f, 1.0f, -0.235f, 0.0f, 0.542f, 0.57f, 1.0f,
+ -0.233f, 0.0f, 0.541f, 0.572f, 1.0f, -0.23f, 0.0f, 0.54f, 0.574f, 1.0f, -0.227f, 0.0f, 0.539f, 0.575f, 1.0f, -0.224f, 0.0f, 0.538f, 0.576f, 1.0f,
+ -0.221f, 0.0f, 0.537f, 0.577f, 1.0f, -0.219f, 0.0f, 0.535f, 0.578f, 1.0f, -0.216f, 0.0f, 0.534f, 0.578f, 1.0f, -0.213f, 0.0f, 0.533f, 0.579f, 1.0f,
+ -0.211f, 0.0f, 0.532f, 0.579f, 1.0f, -0.208f, 0.0f, 0.53f, 0.579f, 1.0f, -0.206f, 0.0f, 0.529f, 0.578f, 1.0f, -0.203f, 0.0f, 0.528f, 0.578f, 1.0f,
+ -0.2f, 0.0f, 0.526f, 0.577f, 1.0f, -0.198f, 0.0f, 0.525f, 0.576f, 1.0f, -0.195f, 0.0f, 0.523f, 0.575f, 1.0f, -0.193f, 0.0f, 0.522f, 0.574f, 1.0f,
+ -0.19f, 0.0f, 0.52f, 0.572f, 1.0f, -0.188f, 0.0f, 0.518f, 0.571f, 1.0f, -0.185f, 0.0f, 0.517f, 0.569f, 1.0f, -0.182f, 0.0f, 0.515f, 0.568f, 1.0f,
+ -0.18f, 0.0f, 0.513f, 0.567f, 1.0f, -0.177f, 0.0f, 0.512f, 0.565f, 1.0f, -0.174f, 0.0f, 0.51f, 0.564f, 1.0f, -0.172f, 0.0f, 0.508f, 0.562f, 1.0f,
+ -0.169f, 0.0f, 0.506f, 0.56f, 1.0f, -0.166f, 0.0f, 0.504f, 0.559f, 1.0f, -0.164f, 0.0f, 0.502f, 0.556f, 1.0f, -0.161f, 0.0f, 0.501f, 0.554f, 1.0f,
+ -0.158f, 0.0f, 0.499f, 0.552f, 1.0f, -0.155f, 0.0f, 0.497f, 0.55f, 1.0f, -0.153f, 0.0f, 0.495f, 0.547f, 1.0f, -0.15f, 0.0f, 0.493f, 0.545f, 1.0f,
+ -0.147f, 0.0f, 0.491f, 0.543f, 1.0f, -0.144f, 0.0f, 0.489f, 0.54f, 1.0f, -0.142f, 0.0f, 0.487f, 0.538f, 1.0f, -0.139f, 0.0f, 0.485f, 0.536f, 1.0f,
+ -0.136f, 0.0f, 0.483f, 0.533f, 1.0f, -0.133f, 0.0f, 0.481f, 0.53f, 1.0f, -0.13f, 0.0f, 0.479f, 0.527f, 1.0f, -0.127f, 0.0f, 0.477f, 0.524f, 1.0f,
+ -0.124f, 0.0f, 0.475f, 0.521f, 1.0f, -0.121f, 0.0f, 0.473f, 0.519f, 1.0f, -0.118f, 0.0f, 0.471f, 0.516f, 1.0f, -0.115f, 0.0f, 0.469f, 0.514f, 1.0f,
+ -0.112f, 0.0f, 0.467f, 0.511f, 1.0f, -0.109f, 0.0f, 0.465f, 0.509f, 1.0f, -0.106f, 0.0f, 0.463f, 0.506f, 1.0f, -0.103f, 0.0f, 0.461f, 0.503f, 1.0f,
+ -0.099f, 0.0f, 0.458f, 0.501f, 1.0f, -0.096f, 0.0f, 0.456f, 0.5f, 1.0f, -0.093f, 0.0f, 0.454f, 0.498f, 1.0f, -0.09f, 0.0f, 0.452f, 0.497f, 1.0f,
+ -0.086f, 0.0f, 0.45f, 0.496f, 1.0f, -0.083f, 0.0f, 0.448f, 0.496f, 1.0f, -0.079f, 0.0f, 0.446f, 0.495f, 1.0f, -0.076f, 0.0f, 0.444f, 0.495f, 1.0f,
+ -0.072f, 0.0f, 0.442f, 0.494f, 1.0f, -0.069f, 0.0f, 0.44f, 0.494f, 1.0f, -0.065f, 0.0f, 0.438f, 0.494f, 1.0f, -0.062f, 0.0f, 0.436f, 0.494f, 1.0f,
+ -0.058f, 0.0f, 0.435f, 0.494f, 1.0f, -0.054f, 0.0f, 0.433f, 0.494f, 1.0f, -0.05f, 0.0f, 0.431f, 0.494f, 1.0f, -0.046f, 0.0f, 0.43f, 0.494f, 1.0f,
+ -0.042f, 0.0f, 0.428f, 0.494f, 1.0f, -0.038f, 0.0f, 0.427f, 0.494f, 1.0f, -0.033f, 0.0f, 0.426f, 0.494f, 1.0f, -0.029f, 0.0f, 0.425f, 0.494f, 1.0f,
+ -0.025f, 0.0f, 0.424f, 0.494f, 1.0f, -0.02f, 0.0f, 0.423f, 0.494f, 1.0f, -0.015f, 0.0f, 0.422f, 0.494f, 1.0f, -0.011f, 0.0f, 0.422f, 0.494f, 1.0f,
+ -0.006f, 0.0f, 0.421f, 0.494f, 1.0f, -0.001f, 0.0f, 0.421f, 0.495f, 1.0f, 0.004f, 0.0f, 0.421f, 0.495f, 1.0f, 0.009f, 0.0f, 0.421f, 0.495f, 1.0f,
+ 0.014f, 0.0f, 0.422f, 0.495f, 1.0f, 0.019f, 0.0f, 0.422f, 0.495f, 1.0f, 0.024f, 0.0f, 0.423f, 0.495f, 1.0f, 0.029f, 0.0f, 0.424f, 0.495f, 1.0f,
+ 0.034f, 0.0f, 0.426f, 0.495f, 1.0f, 0.039f, 0.0f, 0.427f, 0.495f, 1.0f, 0.044f, 0.0f, 0.429f, 0.496f, 1.0f, 0.049f, 0.0f, 0.43f, 0.497f, 1.0f,
+ 0.054f, 0.0f, 0.432f, 0.498f, 1.0f, 0.059f, 0.0f, 0.435f, 0.5f, 1.0f, 0.064f, 0.0f, 0.438f, 0.502f, 1.0f, 0.069f, 0.0f, 0.44f, 0.506f, 1.0f,
+ 0.074f, 0.0f, 0.443f, 0.51f, 1.0f, 0.08f, 0.0f, 0.446f, 0.516f, 1.0f, 0.085f, 0.0f, 0.45f, 0.522f, 1.0f, 0.09f, 0.0f, 0.453f, 0.528f, 1.0f,
+ 0.095f, 0.0f, 0.456f, 0.533f, 1.0f, 0.101f, 0.0f, 0.46f, 0.537f, 1.0f, 0.107f, 0.0f, 0.463f, 0.539f, 1.0f, 0.112f, 0.0f, 0.467f, 0.542f, 1.0f,
+ 0.118f, 0.0f, 0.471f, 0.543f, 1.0f, 0.124f, 0.0f, 0.475f, 0.545f, 1.0f, 0.13f, 0.0f, 0.478f, 0.546f, 1.0f, 0.137f, 0.0f, 0.482f, 0.546f, 1.0f,
+ 0.143f, 0.0f, 0.486f, 0.547f, 1.0f, 0.149f, 0.0f, 0.49f, 0.546f, 1.0f, 0.156f, 0.0f, 0.493f, 0.544f, 1.0f, 0.163f, 0.0f, 0.497f, 0.54f, 1.0f,
+ 0.17f, 0.0f, 0.5f, 0.533f, 1.0f, 0.176f, 0.0f, 0.503f, 0.525f, 1.0f, 0.183f, 0.0f, 0.507f, 0.515f, 1.0f, 0.191f, 0.0f, 0.509f, 0.503f, 1.0f,
+ 0.198f, 0.0f, 0.512f, 0.491f, 1.0f, 0.205f, 0.0f, 0.515f, 0.477f, 1.0f, 0.214f, 0.0f, 0.518f, 0.462f, 1.0f, 0.222f, 0.0f, 0.521f, 0.445f, 1.0f,
+ 0.23f, 0.0f, 0.524f, 0.427f, 1.0f, 0.238f, 0.0f, 0.527f, 0.409f, 1.0f, 0.245f, 0.0f, 0.529f, 0.388f, 1.0f, 0.254f, 0.0f, 0.531f, 0.366f, 1.0f,
+ 0.262f, 0.0f, 0.532f, 0.343f, 1.0f, 0.272f, 0.0f, 0.533f, 0.317f, 1.0f, 0.282f, 0.0f, 0.534f, 0.289f, 1.0f, 0.292f, 0.0f, 0.535f, 0.258f, 1.0f,
+ 0.301f, 0.0f, 0.535f, 0.224f, 1.0f, 0.311f, 0.0f, 0.536f, 0.189f, 1.0f, 0.32f, 0.0f, 0.536f, 0.153f, 1.0f, 0.328f, 0.0f, 0.536f, 0.117f, 1.0f,
+ 0.338f, 0.0f, 0.537f, 0.084f, 1.0f, 0.346f, 0.0f, 0.537f, 0.057f, 1.0f, 0.353f, 0.0f, 0.536f, 0.037f, 1.0f, 0.361f, 0.0f, 0.536f, 0.022f, 1.0f,
+ 0.37f, 0.0f, 0.537f, 0.013f, 1.0f, 0.376f, 0.0f, 0.536f, 0.007f, 1.0f, 0.384f, 0.0f, 0.536f, 0.004f, 1.0f, 0.39f, 0.0f, 0.536f, 0.002f, 1.0f,
+ 0.399f, 0.0f, 0.535f, 0.0f, 1.0f,
+};
+
+static const float data33[69 * GP_PRIM_DATABUF_SIZE] = {
+ -0.308f, 0.0f, 0.151f, 0.363f, 1.0f, -0.31f, 0.0f, 0.15f, 0.377f, 1.0f, -0.311f, 0.0f, 0.149f, 0.386f, 1.0f, -0.313f, 0.0f, 0.149f, 0.397f, 1.0f,
+ -0.314f, 0.0f, 0.149f, 0.408f, 1.0f, -0.316f, 0.0f, 0.148f, 0.42f, 1.0f, -0.318f, 0.0f, 0.148f, 0.431f, 1.0f, -0.32f, 0.0f, 0.148f, 0.443f, 1.0f,
+ -0.322f, 0.0f, 0.148f, 0.455f, 1.0f, -0.325f, 0.0f, 0.149f, 0.467f, 1.0f, -0.327f, 0.0f, 0.149f, 0.478f, 1.0f, -0.33f, 0.0f, 0.151f, 0.49f, 1.0f,
+ -0.333f, 0.0f, 0.152f, 0.501f, 1.0f, -0.336f, 0.0f, 0.154f, 0.512f, 1.0f, -0.34f, 0.0f, 0.157f, 0.522f, 1.0f, -0.343f, 0.0f, 0.161f, 0.533f, 1.0f,
+ -0.346f, 0.0f, 0.166f, 0.543f, 1.0f, -0.349f, 0.0f, 0.171f, 0.553f, 1.0f, -0.351f, 0.0f, 0.178f, 0.563f, 1.0f, -0.352f, 0.0f, 0.186f, 0.572f, 1.0f,
+ -0.353f, 0.0f, 0.193f, 0.582f, 1.0f, -0.352f, 0.0f, 0.2f, 0.591f, 1.0f, -0.351f, 0.0f, 0.206f, 0.6f, 1.0f, -0.349f, 0.0f, 0.211f, 0.608f, 1.0f,
+ -0.347f, 0.0f, 0.215f, 0.616f, 1.0f, -0.345f, 0.0f, 0.219f, 0.623f, 1.0f, -0.343f, 0.0f, 0.222f, 0.63f, 1.0f, -0.341f, 0.0f, 0.224f, 0.637f, 1.0f,
+ -0.339f, 0.0f, 0.226f, 0.642f, 1.0f, -0.337f, 0.0f, 0.228f, 0.647f, 1.0f, -0.335f, 0.0f, 0.229f, 0.652f, 1.0f, -0.333f, 0.0f, 0.23f, 0.656f, 1.0f,
+ -0.332f, 0.0f, 0.231f, 0.66f, 1.0f, -0.33f, 0.0f, 0.232f, 0.663f, 1.0f, -0.328f, 0.0f, 0.232f, 0.666f, 1.0f, -0.327f, 0.0f, 0.233f, 0.669f, 1.0f,
+ -0.325f, 0.0f, 0.233f, 0.672f, 1.0f, -0.324f, 0.0f, 0.234f, 0.676f, 1.0f, -0.322f, 0.0f, 0.234f, 0.679f, 1.0f, -0.321f, 0.0f, 0.234f, 0.682f, 1.0f,
+ -0.319f, 0.0f, 0.234f, 0.686f, 1.0f, -0.317f, 0.0f, 0.234f, 0.689f, 1.0f, -0.316f, 0.0f, 0.234f, 0.693f, 1.0f, -0.314f, 0.0f, 0.234f, 0.697f, 1.0f,
+ -0.312f, 0.0f, 0.233f, 0.701f, 1.0f, -0.31f, 0.0f, 0.232f, 0.705f, 1.0f, -0.307f, 0.0f, 0.231f, 0.709f, 1.0f, -0.305f, 0.0f, 0.23f, 0.713f, 1.0f,
+ -0.302f, 0.0f, 0.228f, 0.716f, 1.0f, -0.299f, 0.0f, 0.225f, 0.719f, 1.0f, -0.295f, 0.0f, 0.222f, 0.722f, 1.0f, -0.292f, 0.0f, 0.217f, 0.725f, 1.0f,
+ -0.289f, 0.0f, 0.21f, 0.727f, 1.0f, -0.287f, 0.0f, 0.202f, 0.728f, 1.0f, -0.285f, 0.0f, 0.194f, 0.729f, 1.0f, -0.286f, 0.0f, 0.185f, 0.729f, 1.0f,
+ -0.287f, 0.0f, 0.178f, 0.728f, 1.0f, -0.289f, 0.0f, 0.171f, 0.726f, 1.0f, -0.292f, 0.0f, 0.166f, 0.723f, 1.0f, -0.294f, 0.0f, 0.162f, 0.717f, 1.0f,
+ -0.297f, 0.0f, 0.159f, 0.71f, 1.0f, -0.299f, 0.0f, 0.157f, 0.701f, 1.0f, -0.301f, 0.0f, 0.155f, 0.689f, 1.0f, -0.303f, 0.0f, 0.154f, 0.675f, 1.0f,
+ -0.305f, 0.0f, 0.152f, 0.659f, 1.0f, -0.306f, 0.0f, 0.151f, 0.641f, 1.0f, -0.308f, 0.0f, 0.151f, 0.62f, 1.0f, -0.309f, 0.0f, 0.15f, 0.602f, 1.0f,
+ -0.31f, 0.0f, 0.15f, 0.572f, 1.0f,
+};
+
+static const float data34[57 * GP_PRIM_DATABUF_SIZE] = {
+ 0.302f, 0.0f, 0.166f, 0.25f, 1.0f, 0.301f, 0.0f, 0.167f, 0.319f, 1.0f, 0.3f, 0.0f, 0.167f, 0.363f, 1.0f, 0.299f, 0.0f, 0.167f, 0.414f, 1.0f,
+ 0.298f, 0.0f, 0.167f, 0.459f, 1.0f, 0.296f, 0.0f, 0.168f, 0.501f, 1.0f, 0.295f, 0.0f, 0.168f, 0.539f, 1.0f, 0.293f, 0.0f, 0.169f, 0.573f, 1.0f,
+ 0.291f, 0.0f, 0.17f, 0.603f, 1.0f, 0.289f, 0.0f, 0.171f, 0.629f, 1.0f, 0.286f, 0.0f, 0.173f, 0.652f, 1.0f, 0.283f, 0.0f, 0.176f, 0.672f, 1.0f,
+ 0.279f, 0.0f, 0.18f, 0.69f, 1.0f, 0.276f, 0.0f, 0.186f, 0.705f, 1.0f, 0.272f, 0.0f, 0.195f, 0.719f, 1.0f, 0.271f, 0.0f, 0.205f, 0.73f, 1.0f,
+ 0.272f, 0.0f, 0.217f, 0.741f, 1.0f, 0.275f, 0.0f, 0.227f, 0.75f, 1.0f, 0.279f, 0.0f, 0.234f, 0.758f, 1.0f, 0.283f, 0.0f, 0.24f, 0.765f, 1.0f,
+ 0.287f, 0.0f, 0.243f, 0.771f, 1.0f, 0.291f, 0.0f, 0.245f, 0.776f, 1.0f, 0.294f, 0.0f, 0.247f, 0.781f, 1.0f, 0.296f, 0.0f, 0.248f, 0.785f, 1.0f,
+ 0.299f, 0.0f, 0.249f, 0.789f, 1.0f, 0.301f, 0.0f, 0.249f, 0.793f, 1.0f, 0.303f, 0.0f, 0.249f, 0.796f, 1.0f, 0.305f, 0.0f, 0.25f, 0.799f, 1.0f,
+ 0.306f, 0.0f, 0.25f, 0.802f, 1.0f, 0.308f, 0.0f, 0.249f, 0.805f, 1.0f, 0.31f, 0.0f, 0.249f, 0.808f, 1.0f, 0.311f, 0.0f, 0.249f, 0.81f, 1.0f,
+ 0.313f, 0.0f, 0.249f, 0.813f, 1.0f, 0.314f, 0.0f, 0.248f, 0.816f, 1.0f, 0.316f, 0.0f, 0.248f, 0.819f, 1.0f, 0.317f, 0.0f, 0.247f, 0.822f, 1.0f,
+ 0.319f, 0.0f, 0.246f, 0.825f, 1.0f, 0.321f, 0.0f, 0.245f, 0.828f, 1.0f, 0.323f, 0.0f, 0.244f, 0.832f, 1.0f, 0.325f, 0.0f, 0.243f, 0.835f, 1.0f,
+ 0.328f, 0.0f, 0.24f, 0.838f, 1.0f, 0.33f, 0.0f, 0.237f, 0.841f, 1.0f, 0.333f, 0.0f, 0.233f, 0.844f, 1.0f, 0.337f, 0.0f, 0.228f, 0.847f, 1.0f,
+ 0.339f, 0.0f, 0.219f, 0.849f, 1.0f, 0.341f, 0.0f, 0.209f, 0.852f, 1.0f, 0.34f, 0.0f, 0.197f, 0.854f, 1.0f, 0.336f, 0.0f, 0.186f, 0.856f, 1.0f,
+ 0.331f, 0.0f, 0.178f, 0.858f, 1.0f, 0.325f, 0.0f, 0.173f, 0.86f, 1.0f, 0.321f, 0.0f, 0.17f, 0.861f, 1.0f, 0.318f, 0.0f, 0.169f, 0.862f, 1.0f,
+ 0.315f, 0.0f, 0.168f, 0.864f, 1.0f, 0.312f, 0.0f, 0.167f, 0.865f, 1.0f, 0.311f, 0.0f, 0.167f, 0.866f, 1.0f, 0.309f, 0.0f, 0.166f, 0.867f, 1.0f,
+ 0.308f, 0.0f, 0.166f, 0.868f, 1.0f,
+};
+
+static const float data35[261 * GP_PRIM_DATABUF_SIZE] = {
+ -0.685f, 0.0f, 0.408f, 0.0f, 1.0f, -0.683f, 0.0f, 0.41f, 0.023f, 1.0f, -0.681f, 0.0f, 0.412f, 0.051f, 1.0f, -0.679f, 0.0f, 0.414f, 0.092f, 1.0f,
+ -0.678f, 0.0f, 0.415f, 0.125f, 1.0f, -0.676f, 0.0f, 0.417f, 0.149f, 1.0f, -0.674f, 0.0f, 0.419f, 0.167f, 1.0f, -0.672f, 0.0f, 0.42f, 0.183f, 1.0f,
+ -0.67f, 0.0f, 0.422f, 0.199f, 1.0f, -0.668f, 0.0f, 0.424f, 0.218f, 1.0f, -0.666f, 0.0f, 0.426f, 0.237f, 1.0f, -0.664f, 0.0f, 0.429f, 0.257f, 1.0f,
+ -0.661f, 0.0f, 0.431f, 0.275f, 1.0f, -0.659f, 0.0f, 0.434f, 0.291f, 1.0f, -0.657f, 0.0f, 0.436f, 0.305f, 1.0f, -0.655f, 0.0f, 0.439f, 0.315f, 1.0f,
+ -0.653f, 0.0f, 0.442f, 0.322f, 1.0f, -0.65f, 0.0f, 0.444f, 0.327f, 1.0f, -0.648f, 0.0f, 0.447f, 0.331f, 1.0f, -0.646f, 0.0f, 0.45f, 0.334f, 1.0f,
+ -0.643f, 0.0f, 0.453f, 0.334f, 1.0f, -0.641f, 0.0f, 0.456f, 0.334f, 1.0f, -0.639f, 0.0f, 0.459f, 0.334f, 1.0f, -0.636f, 0.0f, 0.462f, 0.333f, 1.0f,
+ -0.634f, 0.0f, 0.466f, 0.332f, 1.0f, -0.631f, 0.0f, 0.469f, 0.332f, 1.0f, -0.628f, 0.0f, 0.473f, 0.332f, 1.0f, -0.625f, 0.0f, 0.476f, 0.333f, 1.0f,
+ -0.622f, 0.0f, 0.48f, 0.335f, 1.0f, -0.618f, 0.0f, 0.483f, 0.338f, 1.0f, -0.615f, 0.0f, 0.488f, 0.342f, 1.0f, -0.611f, 0.0f, 0.492f, 0.347f, 1.0f,
+ -0.608f, 0.0f, 0.495f, 0.352f, 1.0f, -0.605f, 0.0f, 0.5f, 0.358f, 1.0f, -0.601f, 0.0f, 0.505f, 0.363f, 1.0f, -0.597f, 0.0f, 0.509f, 0.366f, 1.0f,
+ -0.593f, 0.0f, 0.514f, 0.367f, 1.0f, -0.589f, 0.0f, 0.518f, 0.367f, 1.0f, -0.585f, 0.0f, 0.522f, 0.369f, 1.0f, -0.582f, 0.0f, 0.526f, 0.372f, 1.0f,
+ -0.578f, 0.0f, 0.531f, 0.376f, 1.0f, -0.575f, 0.0f, 0.535f, 0.382f, 1.0f, -0.571f, 0.0f, 0.539f, 0.388f, 1.0f, -0.567f, 0.0f, 0.543f, 0.394f, 1.0f,
+ -0.563f, 0.0f, 0.547f, 0.4f, 1.0f, -0.56f, 0.0f, 0.551f, 0.406f, 1.0f, -0.556f, 0.0f, 0.555f, 0.411f, 1.0f, -0.552f, 0.0f, 0.559f, 0.415f, 1.0f,
+ -0.548f, 0.0f, 0.563f, 0.418f, 1.0f, -0.544f, 0.0f, 0.566f, 0.419f, 1.0f, -0.54f, 0.0f, 0.569f, 0.42f, 1.0f, -0.537f, 0.0f, 0.572f, 0.421f, 1.0f,
+ -0.533f, 0.0f, 0.576f, 0.421f, 1.0f, -0.529f, 0.0f, 0.579f, 0.421f, 1.0f, -0.526f, 0.0f, 0.582f, 0.422f, 1.0f, -0.523f, 0.0f, 0.585f, 0.422f, 1.0f,
+ -0.52f, 0.0f, 0.588f, 0.423f, 1.0f, -0.516f, 0.0f, 0.591f, 0.426f, 1.0f, -0.513f, 0.0f, 0.594f, 0.43f, 1.0f, -0.51f, 0.0f, 0.597f, 0.435f, 1.0f,
+ -0.507f, 0.0f, 0.6f, 0.441f, 1.0f, -0.504f, 0.0f, 0.603f, 0.447f, 1.0f, -0.501f, 0.0f, 0.606f, 0.453f, 1.0f, -0.498f, 0.0f, 0.609f, 0.458f, 1.0f,
+ -0.496f, 0.0f, 0.611f, 0.461f, 1.0f, -0.493f, 0.0f, 0.614f, 0.465f, 1.0f, -0.49f, 0.0f, 0.616f, 0.468f, 1.0f, -0.487f, 0.0f, 0.619f, 0.472f, 1.0f,
+ -0.484f, 0.0f, 0.621f, 0.476f, 1.0f, -0.482f, 0.0f, 0.624f, 0.48f, 1.0f, -0.479f, 0.0f, 0.627f, 0.484f, 1.0f, -0.476f, 0.0f, 0.629f, 0.487f, 1.0f,
+ -0.473f, 0.0f, 0.632f, 0.491f, 1.0f, -0.471f, 0.0f, 0.634f, 0.495f, 1.0f, -0.468f, 0.0f, 0.637f, 0.499f, 1.0f, -0.465f, 0.0f, 0.639f, 0.504f, 1.0f,
+ -0.462f, 0.0f, 0.641f, 0.508f, 1.0f, -0.459f, 0.0f, 0.643f, 0.513f, 1.0f, -0.456f, 0.0f, 0.646f, 0.519f, 1.0f, -0.453f, 0.0f, 0.648f, 0.525f, 1.0f,
+ -0.45f, 0.0f, 0.65f, 0.533f, 1.0f, -0.447f, 0.0f, 0.652f, 0.54f, 1.0f, -0.444f, 0.0f, 0.655f, 0.546f, 1.0f, -0.441f, 0.0f, 0.657f, 0.553f, 1.0f,
+ -0.438f, 0.0f, 0.659f, 0.56f, 1.0f, -0.435f, 0.0f, 0.662f, 0.567f, 1.0f, -0.432f, 0.0f, 0.664f, 0.574f, 1.0f, -0.429f, 0.0f, 0.666f, 0.58f, 1.0f,
+ -0.426f, 0.0f, 0.669f, 0.585f, 1.0f, -0.423f, 0.0f, 0.671f, 0.591f, 1.0f, -0.419f, 0.0f, 0.673f, 0.595f, 1.0f, -0.416f, 0.0f, 0.675f, 0.6f, 1.0f,
+ -0.412f, 0.0f, 0.678f, 0.604f, 1.0f, -0.409f, 0.0f, 0.68f, 0.609f, 1.0f, -0.405f, 0.0f, 0.682f, 0.613f, 1.0f, -0.401f, 0.0f, 0.684f, 0.618f, 1.0f,
+ -0.398f, 0.0f, 0.687f, 0.622f, 1.0f, -0.394f, 0.0f, 0.689f, 0.627f, 1.0f, -0.39f, 0.0f, 0.692f, 0.632f, 1.0f, -0.386f, 0.0f, 0.694f, 0.638f, 1.0f,
+ -0.381f, 0.0f, 0.697f, 0.643f, 1.0f, -0.377f, 0.0f, 0.7f, 0.649f, 1.0f, -0.373f, 0.0f, 0.702f, 0.654f, 1.0f, -0.368f, 0.0f, 0.705f, 0.659f, 1.0f,
+ -0.363f, 0.0f, 0.707f, 0.663f, 1.0f, -0.359f, 0.0f, 0.71f, 0.667f, 1.0f, -0.354f, 0.0f, 0.712f, 0.671f, 1.0f, -0.349f, 0.0f, 0.715f, 0.674f, 1.0f,
+ -0.345f, 0.0f, 0.717f, 0.677f, 1.0f, -0.34f, 0.0f, 0.72f, 0.68f, 1.0f, -0.335f, 0.0f, 0.722f, 0.683f, 1.0f, -0.33f, 0.0f, 0.725f, 0.685f, 1.0f,
+ -0.326f, 0.0f, 0.727f, 0.687f, 1.0f, -0.321f, 0.0f, 0.73f, 0.689f, 1.0f, -0.316f, 0.0f, 0.732f, 0.691f, 1.0f, -0.312f, 0.0f, 0.734f, 0.693f, 1.0f,
+ -0.307f, 0.0f, 0.736f, 0.694f, 1.0f, -0.302f, 0.0f, 0.738f, 0.696f, 1.0f, -0.298f, 0.0f, 0.74f, 0.697f, 1.0f, -0.293f, 0.0f, 0.741f, 0.698f, 1.0f,
+ -0.288f, 0.0f, 0.743f, 0.699f, 1.0f, -0.284f, 0.0f, 0.745f, 0.699f, 1.0f, -0.279f, 0.0f, 0.746f, 0.7f, 1.0f, -0.275f, 0.0f, 0.748f, 0.701f, 1.0f,
+ -0.27f, 0.0f, 0.749f, 0.702f, 1.0f, -0.265f, 0.0f, 0.751f, 0.702f, 1.0f, -0.261f, 0.0f, 0.752f, 0.704f, 1.0f, -0.256f, 0.0f, 0.753f, 0.705f, 1.0f,
+ -0.252f, 0.0f, 0.755f, 0.706f, 1.0f, -0.247f, 0.0f, 0.756f, 0.707f, 1.0f, -0.242f, 0.0f, 0.757f, 0.709f, 1.0f, -0.237f, 0.0f, 0.758f, 0.711f, 1.0f,
+ -0.233f, 0.0f, 0.759f, 0.713f, 1.0f, -0.228f, 0.0f, 0.761f, 0.715f, 1.0f, -0.223f, 0.0f, 0.762f, 0.717f, 1.0f, -0.218f, 0.0f, 0.763f, 0.719f, 1.0f,
+ -0.213f, 0.0f, 0.764f, 0.721f, 1.0f, -0.209f, 0.0f, 0.765f, 0.723f, 1.0f, -0.204f, 0.0f, 0.765f, 0.726f, 1.0f, -0.199f, 0.0f, 0.766f, 0.728f, 1.0f,
+ -0.194f, 0.0f, 0.767f, 0.73f, 1.0f, -0.189f, 0.0f, 0.768f, 0.731f, 1.0f, -0.183f, 0.0f, 0.769f, 0.733f, 1.0f, -0.178f, 0.0f, 0.77f, 0.735f, 1.0f,
+ -0.173f, 0.0f, 0.77f, 0.736f, 1.0f, -0.168f, 0.0f, 0.771f, 0.738f, 1.0f, -0.163f, 0.0f, 0.772f, 0.739f, 1.0f, -0.158f, 0.0f, 0.772f, 0.741f, 1.0f,
+ -0.152f, 0.0f, 0.773f, 0.742f, 1.0f, -0.147f, 0.0f, 0.774f, 0.744f, 1.0f, -0.142f, 0.0f, 0.774f, 0.746f, 1.0f, -0.137f, 0.0f, 0.775f, 0.748f, 1.0f,
+ -0.132f, 0.0f, 0.775f, 0.749f, 1.0f, -0.127f, 0.0f, 0.776f, 0.751f, 1.0f, -0.122f, 0.0f, 0.776f, 0.752f, 1.0f, -0.117f, 0.0f, 0.776f, 0.753f, 1.0f,
+ -0.112f, 0.0f, 0.777f, 0.754f, 1.0f, -0.108f, 0.0f, 0.777f, 0.755f, 1.0f, -0.103f, 0.0f, 0.777f, 0.755f, 1.0f, -0.099f, 0.0f, 0.777f, 0.756f, 1.0f,
+ -0.095f, 0.0f, 0.778f, 0.757f, 1.0f, -0.09f, 0.0f, 0.778f, 0.758f, 1.0f, -0.086f, 0.0f, 0.778f, 0.759f, 1.0f, -0.082f, 0.0f, 0.778f, 0.759f, 1.0f,
+ -0.077f, 0.0f, 0.778f, 0.76f, 1.0f, -0.073f, 0.0f, 0.779f, 0.76f, 1.0f, -0.069f, 0.0f, 0.779f, 0.761f, 1.0f, -0.064f, 0.0f, 0.779f, 0.761f, 1.0f,
+ -0.06f, 0.0f, 0.779f, 0.761f, 1.0f, -0.055f, 0.0f, 0.78f, 0.762f, 1.0f, -0.051f, 0.0f, 0.78f, 0.762f, 1.0f, -0.046f, 0.0f, 0.78f, 0.762f, 1.0f,
+ -0.041f, 0.0f, 0.78f, 0.762f, 1.0f, -0.037f, 0.0f, 0.781f, 0.762f, 1.0f, -0.032f, 0.0f, 0.781f, 0.763f, 1.0f, -0.027f, 0.0f, 0.781f, 0.763f, 1.0f,
+ -0.022f, 0.0f, 0.781f, 0.763f, 1.0f, -0.017f, 0.0f, 0.781f, 0.764f, 1.0f, -0.012f, 0.0f, 0.782f, 0.764f, 1.0f, -0.006f, 0.0f, 0.782f, 0.764f, 1.0f,
+ -0.001f, 0.0f, 0.782f, 0.765f, 1.0f, 0.004f, 0.0f, 0.782f, 0.766f, 1.0f, 0.009f, 0.0f, 0.782f, 0.766f, 1.0f, 0.015f, 0.0f, 0.782f, 0.767f, 1.0f,
+ 0.02f, 0.0f, 0.782f, 0.768f, 1.0f, 0.025f, 0.0f, 0.782f, 0.769f, 1.0f, 0.031f, 0.0f, 0.782f, 0.77f, 1.0f, 0.036f, 0.0f, 0.782f, 0.771f, 1.0f,
+ 0.042f, 0.0f, 0.782f, 0.772f, 1.0f, 0.048f, 0.0f, 0.782f, 0.773f, 1.0f, 0.053f, 0.0f, 0.782f, 0.774f, 1.0f, 0.059f, 0.0f, 0.782f, 0.775f, 1.0f,
+ 0.065f, 0.0f, 0.782f, 0.775f, 1.0f, 0.07f, 0.0f, 0.782f, 0.776f, 1.0f, 0.076f, 0.0f, 0.782f, 0.776f, 1.0f, 0.082f, 0.0f, 0.782f, 0.776f, 1.0f,
+ 0.088f, 0.0f, 0.782f, 0.776f, 1.0f, 0.094f, 0.0f, 0.782f, 0.777f, 1.0f, 0.1f, 0.0f, 0.781f, 0.777f, 1.0f, 0.106f, 0.0f, 0.781f, 0.778f, 1.0f,
+ 0.111f, 0.0f, 0.781f, 0.779f, 1.0f, 0.117f, 0.0f, 0.781f, 0.779f, 1.0f, 0.123f, 0.0f, 0.781f, 0.78f, 1.0f, 0.129f, 0.0f, 0.78f, 0.78f, 1.0f,
+ 0.135f, 0.0f, 0.78f, 0.781f, 1.0f, 0.141f, 0.0f, 0.779f, 0.781f, 1.0f, 0.147f, 0.0f, 0.779f, 0.782f, 1.0f, 0.153f, 0.0f, 0.778f, 0.783f, 1.0f,
+ 0.159f, 0.0f, 0.777f, 0.784f, 1.0f, 0.165f, 0.0f, 0.776f, 0.785f, 1.0f, 0.171f, 0.0f, 0.775f, 0.786f, 1.0f, 0.178f, 0.0f, 0.774f, 0.787f, 1.0f,
+ 0.185f, 0.0f, 0.773f, 0.788f, 1.0f, 0.192f, 0.0f, 0.772f, 0.789f, 1.0f, 0.2f, 0.0f, 0.771f, 0.79f, 1.0f, 0.208f, 0.0f, 0.77f, 0.791f, 1.0f,
+ 0.218f, 0.0f, 0.768f, 0.793f, 1.0f, 0.228f, 0.0f, 0.766f, 0.796f, 1.0f, 0.239f, 0.0f, 0.764f, 0.799f, 1.0f, 0.25f, 0.0f, 0.762f, 0.802f, 1.0f,
+ 0.261f, 0.0f, 0.759f, 0.806f, 1.0f, 0.271f, 0.0f, 0.755f, 0.81f, 1.0f, 0.282f, 0.0f, 0.752f, 0.815f, 1.0f, 0.293f, 0.0f, 0.748f, 0.819f, 1.0f,
+ 0.304f, 0.0f, 0.744f, 0.825f, 1.0f, 0.315f, 0.0f, 0.74f, 0.83f, 1.0f, 0.326f, 0.0f, 0.736f, 0.836f, 1.0f, 0.337f, 0.0f, 0.731f, 0.843f, 1.0f,
+ 0.349f, 0.0f, 0.727f, 0.85f, 1.0f, 0.361f, 0.0f, 0.722f, 0.858f, 1.0f, 0.372f, 0.0f, 0.718f, 0.866f, 1.0f, 0.384f, 0.0f, 0.712f, 0.874f, 1.0f,
+ 0.395f, 0.0f, 0.706f, 0.882f, 1.0f, 0.407f, 0.0f, 0.7f, 0.89f, 1.0f, 0.418f, 0.0f, 0.693f, 0.898f, 1.0f, 0.43f, 0.0f, 0.685f, 0.905f, 1.0f,
+ 0.442f, 0.0f, 0.677f, 0.912f, 1.0f, 0.458f, 0.0f, 0.666f, 0.918f, 1.0f, 0.473f, 0.0f, 0.654f, 0.924f, 1.0f, 0.49f, 0.0f, 0.64f, 0.93f, 1.0f,
+ 0.506f, 0.0f, 0.625f, 0.935f, 1.0f, 0.522f, 0.0f, 0.611f, 0.939f, 1.0f, 0.538f, 0.0f, 0.596f, 0.941f, 1.0f, 0.554f, 0.0f, 0.58f, 0.942f, 1.0f,
+ 0.569f, 0.0f, 0.564f, 0.941f, 1.0f, 0.584f, 0.0f, 0.548f, 0.935f, 1.0f, 0.598f, 0.0f, 0.533f, 0.925f, 1.0f, 0.612f, 0.0f, 0.517f, 0.91f, 1.0f,
+ 0.625f, 0.0f, 0.501f, 0.891f, 1.0f, 0.638f, 0.0f, 0.484f, 0.868f, 1.0f, 0.65f, 0.0f, 0.468f, 0.839f, 1.0f, 0.662f, 0.0f, 0.452f, 0.806f, 1.0f,
+ 0.671f, 0.0f, 0.437f, 0.766f, 1.0f, 0.679f, 0.0f, 0.423f, 0.718f, 1.0f, 0.685f, 0.0f, 0.412f, 0.661f, 1.0f, 0.691f, 0.0f, 0.403f, 0.595f, 1.0f,
+ 0.697f, 0.0f, 0.396f, 0.519f, 1.0f, 0.701f, 0.0f, 0.391f, 0.44f, 1.0f, 0.704f, 0.0f, 0.387f, 0.344f, 1.0f, 0.707f, 0.0f, 0.384f, 0.264f, 1.0f,
+ 0.711f, 0.0f, 0.38f, 0.133f, 1.0f,
+};
+
+/* ***************************************************************** */
+/* Monkey Color Data */
+
+static const ColorTemplate gp_monkey_pct_black = {
+ "Black",
+ {0.0f, 0.0f, 0.0f, 1.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+};
+
+static const ColorTemplate gp_monkey_pct_skin = {
+ "Skin",
+ {0.553f, 0.39f, 0.266f, 0.0f},
+ {0.733f, 0.567f, 0.359f, 1.0f},
+};
+
+static const ColorTemplate gp_monkey_pct_skin_light = {
+ "Skin_Light",
+ {0.553f, 0.39f, 0.266f, 0.0f},
+ {0.913f, 0.828f, 0.637f, 1.0f},
+};
+
+static const ColorTemplate gp_monkey_pct_skin_shadow = {
+ "Skin_Shadow",
+ {0.553f, 0.39f, 0.266f, 0.0f},
+ {0.32f, 0.29f, 0.223f, 1.0f},
+};
+
+static const ColorTemplate gp_monkey_pct_eyes = {
+ "Eyes",
+ {0.553f, 0.39f, 0.266f, 0.0f},
+ {0.773f, 0.762f, 0.73f, 1.0f},
+};
+
+static const ColorTemplate gp_monkey_pct_pupils = {
+ "Pupils",
+ {0.107f, 0.075f, 0.051f, 0.0f},
+ {0.153f, 0.057f, 0.063f, 1.0f},
+};
+
+/* ***************************************************************** */
+/* Monkey API */
+
+/* add a 2D Suzanne (original model created by Matias Mendiola) */
+void ED_gpencil_create_monkey(bContext *C, float mat[4][4])
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob = CTX_data_active_object(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ bGPdata *gpd = (bGPdata *)ob->data;
+ bGPDstroke *gps;
+
+ /* create colors */
+ int color_Black = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_black);
+ int color_Skin = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_skin);
+ int color_Skin_Light = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_skin_light);
+ int color_Skin_Shadow = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_skin_shadow);
+ int color_Eyes = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_eyes);
+ int color_Pupils = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_pupils);
+
+ /* layers */
+ /* NOTE: For now, we just add new layers, to make it easier to separate out old/new instances */
+ bGPDlayer *Colors = BKE_gpencil_layer_addnew(gpd, "Colors", false);
+ bGPDlayer *Lines = BKE_gpencil_layer_addnew(gpd, "Lines", true);
+
+ /* frames */
+ /* NOTE: No need to check for existing, as this will tkae care of it for us */
+ bGPDframe *frameColor = BKE_gpencil_frame_addnew(Colors, cfra_eval);
+ bGPDframe *frameLines = BKE_gpencil_frame_addnew(Lines, cfra_eval);
+
+ /* generate strokes */
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin, 538, 3);
+ BKE_gpencil_stroke_add_points(gps, data0, 538, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Eyes, 136, 3);
+ BKE_gpencil_stroke_add_points(gps, data1, 136, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin, 2, 3);
+ BKE_gpencil_stroke_add_points(gps, data2, 2, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 1, 3);
+ BKE_gpencil_stroke_add_points(gps, data3, 1, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 1, 3);
+ BKE_gpencil_stroke_add_points(gps, data4, 1, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 48, 3);
+ BKE_gpencil_stroke_add_points(gps, data5, 48, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 47, 3);
+ BKE_gpencil_stroke_add_points(gps, data6, 47, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 162, 3);
+ BKE_gpencil_stroke_add_points(gps, data7, 162, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 55, 3);
+ BKE_gpencil_stroke_add_points(gps, data8, 55, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 70, 3);
+ BKE_gpencil_stroke_add_points(gps, data9, 70, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 227, 3);
+ BKE_gpencil_stroke_add_points(gps, data10, 227, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 1, 3);
+ BKE_gpencil_stroke_add_points(gps, data11, 1, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 123, 3);
+ BKE_gpencil_stroke_add_points(gps, data12, 123, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 125, 3);
+ BKE_gpencil_stroke_add_points(gps, data13, 125, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 45, 3);
+ BKE_gpencil_stroke_add_points(gps, data14, 45, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 44, 3);
+ BKE_gpencil_stroke_add_points(gps, data15, 44, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 84, 3);
+ BKE_gpencil_stroke_add_points(gps, data16, 84, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 56, 3);
+ BKE_gpencil_stroke_add_points(gps, data17, 56, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 59, 3);
+ BKE_gpencil_stroke_add_points(gps, data18, 59, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 100, 3);
+ BKE_gpencil_stroke_add_points(gps, data19, 100, mat);
+
+ gps = BKE_gpencil_add_stroke(frameColor, color_Eyes, 136, 3);
+ BKE_gpencil_stroke_add_points(gps, data20, 136, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 353, 3);
+ BKE_gpencil_stroke_add_points(gps, data21, 353, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 309, 3);
+ BKE_gpencil_stroke_add_points(gps, data22, 309, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 209, 3);
+ BKE_gpencil_stroke_add_points(gps, data23, 209, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 133, 3);
+ BKE_gpencil_stroke_add_points(gps, data24, 133, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 389, 3);
+ BKE_gpencil_stroke_add_points(gps, data25, 389, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 41, 3);
+ BKE_gpencil_stroke_add_points(gps, data26, 41, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 77, 3);
+ BKE_gpencil_stroke_add_points(gps, data27, 77, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 257, 3);
+ BKE_gpencil_stroke_add_points(gps, data28, 257, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 205, 3);
+ BKE_gpencil_stroke_add_points(gps, data29, 205, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 33, 3);
+ BKE_gpencil_stroke_add_points(gps, data30, 33, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 37, 3);
+ BKE_gpencil_stroke_add_points(gps, data31, 37, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 201, 3);
+ BKE_gpencil_stroke_add_points(gps, data32, 201, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Pupils, 69, 3);
+ BKE_gpencil_stroke_add_points(gps, data33, 69, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Pupils, 57, 3);
+ BKE_gpencil_stroke_add_points(gps, data34, 57, mat);
+
+ gps = BKE_gpencil_add_stroke(frameLines, color_Black, 261, 3);
+ BKE_gpencil_stroke_add_points(gps, data35, 261, mat);
+
+ /* update depsgraph */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+}
+
+
+/* ***************************************************************** */
diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c
new file mode 100644
index 00000000000..c5020593bcb
--- /dev/null
+++ b/source/blender/editors/gpencil/gpencil_add_stroke.c
@@ -0,0 +1,248 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2017 Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Antonio Vazquez, Matias Mendiola
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/gpencil/gpencil_add_stroke.c
+ * \ingroup edgpencil
+ */
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_context.h"
+#include "BKE_gpencil.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "ED_gpencil.h"
+
+/* Definition of the most important info from a color */
+typedef struct ColorTemplate {
+ const char *name;
+ float line[4];
+ float fill[4];
+} ColorTemplate;
+
+/* Add color an ensure duplications (matched by name) */
+static int gp_stroke_material(Main *bmain, Object *ob, const ColorTemplate *pct)
+{
+ short *totcol = give_totcolp(ob);
+ Material *ma = NULL;
+ for (short i = 0; i < *totcol; i++) {
+ ma = give_current_material(ob, i + 1);
+ if (STREQ(ma->id.name, pct->name)) {
+ return i;
+ }
+ }
+
+ /* create a new one */
+ BKE_object_material_slot_add(bmain, ob);
+ ma = BKE_material_add_gpencil(bmain, pct->name);
+ assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
+
+ copy_v4_v4(ma->gp_style->stroke_rgba, pct->line);
+ copy_v4_v4(ma->gp_style->fill_rgba, pct->fill);
+
+ return BKE_gpencil_get_material_index(ob, ma) - 1;
+}
+
+/* ***************************************************************** */
+/* Stroke Geometry */
+
+static const float data0[175 * GP_PRIM_DATABUF_SIZE] = {
+ -1.281f, 0.0f, -0.315f, 0.038f, 1.0f, -1.269f, 0.0f, -0.302f, 0.069f, 1.0f,
+ -1.261f, 0.0f, -0.293f, 0.089f, 1.0f, -1.251f, 0.0f, -0.282f, 0.112f, 1.0f,
+ -1.241f, 0.0f, -0.271f, 0.134f, 1.0f, -1.23f, 0.0f, -0.259f, 0.155f, 1.0f,
+ -1.219f, 0.0f, -0.247f, 0.175f, 1.0f, -1.208f, 0.0f, -0.234f, 0.194f, 1.0f,
+ -1.196f, 0.0f, -0.221f, 0.211f, 1.0f, -1.184f, 0.0f, -0.208f, 0.227f, 1.0f,
+ -1.172f, 0.0f, -0.194f, 0.242f, 1.0f, -1.159f, 0.0f, -0.18f, 0.256f, 1.0f,
+ -1.147f, 0.0f, -0.165f, 0.268f, 1.0f, -1.134f, 0.0f, -0.151f, 0.28f, 1.0f,
+ -1.121f, 0.0f, -0.136f, 0.29f, 1.0f, -1.108f, 0.0f, -0.121f, 0.299f, 1.0f,
+ -1.094f, 0.0f, -0.106f, 0.307f, 1.0f, -1.08f, 0.0f, -0.091f, 0.315f, 1.0f,
+ -1.066f, 0.0f, -0.076f, 0.322f, 1.0f, -1.052f, 0.0f, -0.061f, 0.329f, 1.0f,
+ -1.037f, 0.0f, -0.047f, 0.335f, 1.0f, -1.022f, 0.0f, -0.032f, 0.341f, 1.0f,
+ -1.007f, 0.0f, -0.017f, 0.346f, 1.0f, -0.991f, 0.0f, -0.003f, 0.351f, 1.0f,
+ -0.975f, 0.0f, 0.012f, 0.355f, 1.0f, -0.959f, 0.0f, 0.027f, 0.36f, 1.0f,
+ -0.942f, 0.0f, 0.041f, 0.364f, 1.0f, -0.926f, 0.0f, 0.056f, 0.368f, 1.0f,
+ -0.909f, 0.0f, 0.071f, 0.371f, 1.0f, -0.893f, 0.0f, 0.086f, 0.373f, 1.0f,
+ -0.876f, 0.0f, 0.1f, 0.376f, 1.0f, -0.859f, 0.0f, 0.115f, 0.377f, 1.0f,
+ -0.842f, 0.0f, 0.129f, 0.378f, 1.0f, -0.824f, 0.0f, 0.144f, 0.379f, 1.0f,
+ -0.807f, 0.0f, 0.158f, 0.379f, 1.0f, -0.79f, 0.0f, 0.172f, 0.379f, 1.0f,
+ -0.773f, 0.0f, 0.186f, 0.38f, 1.0f, -0.755f, 0.0f, 0.199f, 0.38f, 1.0f,
+ -0.738f, 0.0f, 0.212f, 0.381f, 1.0f, -0.721f, 0.0f, 0.224f, 0.382f, 1.0f,
+ -0.703f, 0.0f, 0.236f, 0.384f, 1.0f, -0.686f, 0.0f, 0.248f, 0.386f, 1.0f,
+ -0.67f, 0.0f, 0.26f, 0.388f, 1.0f, -0.653f, 0.0f, 0.27f, 0.39f, 1.0f,
+ -0.637f, 0.0f, 0.28f, 0.393f, 1.0f, -0.621f, 0.0f, 0.29f, 0.396f, 1.0f,
+ -0.605f, 0.0f, 0.298f, 0.399f, 1.0f, -0.589f, 0.0f, 0.306f, 0.403f, 1.0f,
+ -0.574f, 0.0f, 0.313f, 0.407f, 1.0f, -0.559f, 0.0f, 0.319f, 0.411f, 1.0f,
+ -0.544f, 0.0f, 0.325f, 0.415f, 1.0f, -0.53f, 0.0f, 0.331f, 0.42f, 1.0f,
+ -0.516f, 0.0f, 0.336f, 0.425f, 1.0f, -0.503f, 0.0f, 0.34f, 0.431f, 1.0f,
+ -0.489f, 0.0f, 0.344f, 0.437f, 1.0f, -0.477f, 0.0f, 0.347f, 0.443f, 1.0f,
+ -0.464f, 0.0f, 0.35f, 0.45f, 1.0f, -0.452f, 0.0f, 0.352f, 0.457f, 1.0f,
+ -0.44f, 0.0f, 0.354f, 0.464f, 1.0f, -0.429f, 0.0f, 0.355f, 0.471f, 1.0f,
+ -0.418f, 0.0f, 0.355f, 0.479f, 1.0f, -0.407f, 0.0f, 0.355f, 0.487f, 1.0f,
+ -0.397f, 0.0f, 0.354f, 0.495f, 1.0f, -0.387f, 0.0f, 0.353f, 0.503f, 1.0f,
+ -0.378f, 0.0f, 0.351f, 0.512f, 1.0f, -0.368f, 0.0f, 0.348f, 0.52f, 1.0f,
+ -0.36f, 0.0f, 0.344f, 0.528f, 1.0f, -0.351f, 0.0f, 0.34f, 0.537f, 1.0f,
+ -0.344f, 0.0f, 0.336f, 0.545f, 1.0f, -0.336f, 0.0f, 0.33f, 0.553f, 1.0f,
+ -0.329f, 0.0f, 0.324f, 0.562f, 1.0f, -0.322f, 0.0f, 0.318f, 0.57f, 1.0f,
+ -0.316f, 0.0f, 0.31f, 0.579f, 1.0f, -0.311f, 0.0f, 0.303f, 0.588f, 1.0f,
+ -0.306f, 0.0f, 0.294f, 0.597f, 1.0f, -0.301f, 0.0f, 0.285f, 0.606f, 1.0f,
+ -0.297f, 0.0f, 0.275f, 0.615f, 1.0f, -0.293f, 0.0f, 0.264f, 0.625f, 1.0f,
+ -0.29f, 0.0f, 0.253f, 0.635f, 1.0f, -0.288f, 0.0f, 0.241f, 0.644f, 1.0f,
+ -0.286f, 0.0f, 0.229f, 0.654f, 1.0f, -0.285f, 0.0f, 0.216f, 0.664f, 1.0f,
+ -0.284f, 0.0f, 0.202f, 0.675f, 1.0f, -0.283f, 0.0f, 0.188f, 0.685f, 1.0f,
+ -0.283f, 0.0f, 0.173f, 0.696f, 1.0f, -0.284f, 0.0f, 0.158f, 0.707f, 1.0f,
+ -0.285f, 0.0f, 0.142f, 0.718f, 1.0f, -0.286f, 0.0f, 0.125f, 0.729f, 1.0f,
+ -0.288f, 0.0f, 0.108f, 0.74f, 1.0f, -0.29f, 0.0f, 0.091f, 0.751f, 1.0f,
+ -0.293f, 0.0f, 0.073f, 0.761f, 1.0f, -0.295f, 0.0f, 0.054f, 0.772f, 1.0f,
+ -0.298f, 0.0f, 0.035f, 0.782f, 1.0f, -0.302f, 0.0f, 0.016f, 0.793f, 1.0f,
+ -0.305f, 0.0f, -0.004f, 0.804f, 1.0f, -0.309f, 0.0f, -0.024f, 0.815f, 1.0f,
+ -0.313f, 0.0f, -0.044f, 0.828f, 1.0f, -0.317f, 0.0f, -0.065f, 0.843f, 1.0f,
+ -0.321f, 0.0f, -0.085f, 0.86f, 1.0f, -0.326f, 0.0f, -0.106f, 0.879f, 1.0f,
+ -0.33f, 0.0f, -0.127f, 0.897f, 1.0f, -0.335f, 0.0f, -0.148f, 0.915f, 1.0f,
+ -0.339f, 0.0f, -0.168f, 0.932f, 1.0f, -0.344f, 0.0f, -0.189f, 0.947f, 1.0f,
+ -0.348f, 0.0f, -0.21f, 0.962f, 1.0f, -0.353f, 0.0f, -0.23f, 0.974f, 1.0f,
+ -0.357f, 0.0f, -0.25f, 0.985f, 1.0f, -0.361f, 0.0f, -0.27f, 0.995f, 1.0f,
+ -0.365f, 0.0f, -0.29f, 1.004f, 1.0f, -0.369f, 0.0f, -0.309f, 1.011f, 1.0f,
+ -0.372f, 0.0f, -0.328f, 1.018f, 1.0f, -0.375f, 0.0f, -0.347f, 1.024f, 1.0f,
+ -0.377f, 0.0f, -0.365f, 1.029f, 1.0f, -0.379f, 0.0f, -0.383f, 1.033f, 1.0f,
+ -0.38f, 0.0f, -0.4f, 1.036f, 1.0f, -0.38f, 0.0f, -0.417f, 1.037f, 1.0f,
+ -0.38f, 0.0f, -0.434f, 1.037f, 1.0f, -0.379f, 0.0f, -0.449f, 1.035f, 1.0f,
+ -0.377f, 0.0f, -0.464f, 1.032f, 1.0f, -0.374f, 0.0f, -0.478f, 1.029f, 1.0f,
+ -0.371f, 0.0f, -0.491f, 1.026f, 1.0f, -0.366f, 0.0f, -0.503f, 1.023f, 1.0f,
+ -0.361f, 0.0f, -0.513f, 1.021f, 1.0f, -0.354f, 0.0f, -0.523f, 1.019f, 1.0f,
+ -0.347f, 0.0f, -0.531f, 1.017f, 1.0f, -0.339f, 0.0f, -0.538f, 1.016f, 1.0f,
+ -0.33f, 0.0f, -0.543f, 1.016f, 1.0f, -0.32f, 0.0f, -0.547f, 1.016f, 1.0f,
+ -0.31f, 0.0f, -0.549f, 1.016f, 1.0f, -0.298f, 0.0f, -0.55f, 1.017f, 1.0f,
+ -0.286f, 0.0f, -0.55f, 1.017f, 1.0f, -0.274f, 0.0f, -0.548f, 1.018f, 1.0f,
+ -0.261f, 0.0f, -0.544f, 1.017f, 1.0f, -0.247f, 0.0f, -0.539f, 1.017f, 1.0f,
+ -0.232f, 0.0f, -0.533f, 1.016f, 1.0f, -0.218f, 0.0f, -0.525f, 1.015f, 1.0f,
+ -0.202f, 0.0f, -0.515f, 1.013f, 1.0f, -0.186f, 0.0f, -0.503f, 1.009f, 1.0f,
+ -0.169f, 0.0f, -0.49f, 1.005f, 1.0f, -0.151f, 0.0f, -0.475f, 0.998f, 1.0f,
+ -0.132f, 0.0f, -0.458f, 0.99f, 1.0f, -0.112f, 0.0f, -0.44f, 0.98f, 1.0f,
+ -0.091f, 0.0f, -0.42f, 0.968f, 1.0f, -0.069f, 0.0f, -0.398f, 0.955f, 1.0f,
+ -0.045f, 0.0f, -0.375f, 0.939f, 1.0f, -0.021f, 0.0f, -0.35f, 0.923f, 1.0f,
+ 0.005f, 0.0f, -0.324f, 0.908f, 1.0f, 0.031f, 0.0f, -0.297f, 0.895f, 1.0f,
+ 0.06f, 0.0f, -0.268f, 0.882f, 1.0f, 0.089f, 0.0f, -0.238f, 0.87f, 1.0f,
+ 0.12f, 0.0f, -0.207f, 0.858f, 1.0f, 0.153f, 0.0f, -0.175f, 0.844f, 1.0f,
+ 0.187f, 0.0f, -0.14f, 0.828f, 1.0f, 0.224f, 0.0f, -0.104f, 0.81f, 1.0f,
+ 0.262f, 0.0f, -0.067f, 0.79f, 1.0f, 0.302f, 0.0f, -0.027f, 0.769f, 1.0f,
+ 0.344f, 0.0f, 0.014f, 0.747f, 1.0f, 0.388f, 0.0f, 0.056f, 0.724f, 1.0f,
+ 0.434f, 0.0f, 0.1f, 0.7f, 1.0f, 0.483f, 0.0f, 0.145f, 0.676f, 1.0f,
+ 0.533f, 0.0f, 0.191f, 0.651f, 1.0f, 0.585f, 0.0f, 0.238f, 0.625f, 1.0f,
+ 0.637f, 0.0f, 0.284f, 0.599f, 1.0f, 0.69f, 0.0f, 0.33f, 0.573f, 1.0f,
+ 0.746f, 0.0f, 0.376f, 0.546f, 1.0f, 0.802f, 0.0f, 0.421f, 0.516f, 1.0f,
+ 0.859f, 0.0f, 0.464f, 0.483f, 1.0f, 0.915f, 0.0f, 0.506f, 0.446f, 1.0f,
+ 0.97f, 0.0f, 0.545f, 0.407f, 1.0f, 1.023f, 0.0f, 0.581f, 0.365f, 1.0f,
+ 1.075f, 0.0f, 0.614f, 0.322f, 1.0f, 1.122f, 0.0f, 0.643f, 0.28f, 1.0f,
+ 1.169f, 0.0f, 0.671f, 0.236f, 1.0f, 1.207f, 0.0f, 0.693f, 0.202f, 1.0f,
+ 1.264f, 0.0f, 0.725f, 0.155f, 1.0f,
+};
+
+/* ***************************************************************** */
+/* Color Data */
+
+static const ColorTemplate gp_stroke_material_black = {
+ "Black",
+ {0.0f, 0.0f, 0.0f, 1.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+};
+
+static const ColorTemplate gp_stroke_material_white = {
+ "White",
+ {1.0f, 1.0f, 1.0f, 1.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+};
+
+static const ColorTemplate gp_stroke_material_red = {
+ "Red",
+ {1.0f, 0.0f, 0.0f, 1.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+};
+
+static const ColorTemplate gp_stroke_material_green = {
+ "Green",
+ {0.0f, 1.0f, 0.0f, 1.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+};
+
+static const ColorTemplate gp_stroke_material_blue = {
+ "Blue",
+ {0.0f, 0.0f, 1.0f, 1.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+};
+
+static const ColorTemplate gp_stroke_material_grey = {
+ "Grey",
+ {0.358f, 0.358f, 0.358f, 1.0f},
+ {0.5f, 0.5f, 0.5f, 1.0f},
+};
+
+/* ***************************************************************** */
+/* Stroke API */
+
+/* add a Simple stroke with colors (original design created by Daniel M. Lara and Matias Mendiola) */
+void ED_gpencil_create_stroke(bContext *C, float mat[4][4])
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob = CTX_data_active_object(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ bGPdata *gpd = (bGPdata *)ob->data;
+ bGPDstroke *gps;
+
+ /* create colors */
+ int color_black = gp_stroke_material(bmain, ob, &gp_stroke_material_black);
+ gp_stroke_material(bmain, ob, &gp_stroke_material_white);
+ gp_stroke_material(bmain, ob, &gp_stroke_material_red);
+ gp_stroke_material(bmain, ob, &gp_stroke_material_green);
+ gp_stroke_material(bmain, ob, &gp_stroke_material_blue);
+ gp_stroke_material(bmain, ob, &gp_stroke_material_grey);
+
+ /* layers */
+ bGPDlayer *colors = BKE_gpencil_layer_addnew(gpd, "Colors", false);
+ bGPDlayer *lines = BKE_gpencil_layer_addnew(gpd, "Lines", false);
+
+ /* frames */
+ bGPDframe *frame_color = BKE_gpencil_frame_addnew(colors, cfra_eval);
+ bGPDframe *frame_lines = BKE_gpencil_frame_addnew(lines, cfra_eval);
+ UNUSED_VARS(frame_color);
+
+ /* generate stroke */
+ gps = BKE_gpencil_add_stroke(frame_lines, color_black, 175, 3);
+ BKE_gpencil_stroke_add_points(gps, data0, 175, mat);
+
+ /* update depsgraph */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+}
diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c
index 0ddd8700c09..d8be0dd665a 100644
--- a/source/blender/editors/gpencil/gpencil_brush.c
+++ b/source/blender/editors/gpencil/gpencil_brush.c
@@ -48,6 +48,7 @@
#include "BLT_translation.h"
+#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -60,6 +61,9 @@
#include "BKE_library.h"
#include "BKE_report.h"
#include "BKE_screen.h"
+#include "BKE_object_deform.h"
+#include "BKE_colortools.h"
+#include "BKE_material.h"
#include "UI_interface.h"
@@ -80,6 +84,9 @@
#include "GPU_immediate_util.h"
#include "GPU_state.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
#include "gpencil_intern.h"
/* ************************************************ */
@@ -89,7 +96,9 @@
typedef struct tGP_BrushEditData {
/* Current editor/region/etc. */
/* NOTE: This stuff is mainly needed to handle 3D view projection stuff... */
+ Depsgraph *depsgraph;
Scene *scene;
+ Object *object;
ScrArea *sa;
ARegion *ar;
@@ -114,6 +123,10 @@ typedef struct tGP_BrushEditData {
/* Start of new sculpt stroke */
bool first;
+ /* Is multiframe editing enabled, and are we using falloff for that? */
+ bool is_multiframe;
+ bool use_multiframe_falloff;
+
/* Current frame */
int cfra;
@@ -128,6 +141,13 @@ typedef struct tGP_BrushEditData {
/* - effect vector (e.g. 2D/3D translation for grab brush) */
float dvec[3];
+ /* - multiframe falloff factor */
+ float mf_falloff;
+
+ /* active vertex group */
+ int vrgroup;
+
+
/* brush geometry (bounding box) */
rcti brush_rect;
@@ -147,12 +167,34 @@ typedef struct tGP_BrushEditData {
/* Callback for performing some brush operation on a single point */
-typedef bool (*GP_BrushApplyCb)(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
+typedef bool (*GP_BrushApplyCb)(tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index,
const int radius, const int co[2]);
/* ************************************************ */
/* Utility Functions */
+/* apply lock axis reset */
+static void gpsculpt_compute_lock_axis(tGP_BrushEditData *gso, bGPDspoint *pt, const float save_pt[3])
+{
+ if (gso->sa->spacetype != SPACE_VIEW3D) {
+ return;
+ }
+
+ ToolSettings *ts = gso->scene->toolsettings;
+ int axis = ts->gp_sculpt.lock_axis;
+
+ /* lock axis control */
+ if (axis == 1) {
+ pt->x = save_pt[0];
+ }
+ if (axis == 2) {
+ pt->y = save_pt[1];
+ }
+ if (axis == 3) {
+ pt->z = save_pt[2];
+ }
+}
+
/* Context ---------------------------------------- */
/* Get the sculpting settings */
@@ -162,10 +204,18 @@ static GP_BrushEdit_Settings *gpsculpt_get_settings(Scene *scene)
}
/* Get the active brush */
-static GP_EditBrush_Data *gpsculpt_get_brush(Scene *scene)
+static GP_EditBrush_Data *gpsculpt_get_brush(Scene *scene, bool is_weight_mode)
{
GP_BrushEdit_Settings *gset = &scene->toolsettings->gp_sculpt;
- return &gset->brush[gset->brushtype];
+ GP_EditBrush_Data *brush = NULL;
+ if (is_weight_mode) {
+ brush = &gset->brush[gset->weighttype];
+ }
+ else {
+ brush = &gset->brush[gset->brushtype];
+ }
+
+ return brush;
}
/* Brush Operations ------------------------------- */
@@ -181,6 +231,14 @@ static bool gp_brush_invert_check(tGP_BrushEditData *gso)
invert ^= true;
}
+ /* set temporary status */
+ if (invert) {
+ gso->brush->flag |= GP_EDITBRUSH_FLAG_TMP_INVERT;
+ }
+ else {
+ gso->brush->flag &= ~GP_EDITBRUSH_FLAG_TMP_INVERT;
+ }
+
return invert;
}
@@ -208,6 +266,9 @@ static float gp_brush_influence_calc(tGP_BrushEditData *gso, const int radius, c
influence *= fac;
}
+ /* apply multiframe falloff */
+ influence *= gso->mf_falloff;
+
/* return influence */
return influence;
}
@@ -222,29 +283,34 @@ static float gp_brush_influence_calc(tGP_BrushEditData *gso, const int radius, c
/* Smooth Brush */
/* 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, int i,
- const int radius, const int co[2])
+static bool gp_brush_smooth_apply(
+ tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index,
+ const int radius, const int co[2])
{
- GP_EditBrush_Data *brush = gso->brush;
+ // GP_EditBrush_Data *brush = gso->brush;
float inf = gp_brush_influence_calc(gso, radius, co);
- bool affect_pressure = (brush->flag & GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE) != 0;
/* need one flag enabled by default */
- if ((gso->settings->flag & (GP_BRUSHEDIT_FLAG_APPLY_POSITION |
- GP_BRUSHEDIT_FLAG_APPLY_STRENGTH |
- GP_BRUSHEDIT_FLAG_APPLY_THICKNESS)) == 0)
+ if ((gso->settings->flag &
+ (GP_BRUSHEDIT_FLAG_APPLY_POSITION |
+ GP_BRUSHEDIT_FLAG_APPLY_STRENGTH |
+ GP_BRUSHEDIT_FLAG_APPLY_THICKNESS |
+ GP_BRUSHEDIT_FLAG_APPLY_UV)) == 0)
{
gso->settings->flag |= GP_BRUSHEDIT_FLAG_APPLY_POSITION;
}
/* perform smoothing */
if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_POSITION) {
- gp_smooth_stroke(gps, i, inf, affect_pressure);
+ BKE_gpencil_smooth_stroke(gps, pt_index, inf);
}
if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_STRENGTH) {
- gp_smooth_stroke_strength(gps, i, inf);
+ BKE_gpencil_smooth_stroke_strength(gps, pt_index, inf);
}
if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_THICKNESS) {
- gp_smooth_stroke_thickness(gps, i, inf);
+ BKE_gpencil_smooth_stroke_thickness(gps, pt_index, inf);
+ }
+ if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_UV) {
+ BKE_gpencil_smooth_stroke_uv(gps, pt_index, inf);
}
return true;
@@ -254,10 +320,11 @@ static bool gp_brush_smooth_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i
/* Line Thickness Brush */
/* Make lines thicker or thinner by the specified amounts */
-static bool gp_brush_thickness_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
- const int radius, const int co[2])
+static bool gp_brush_thickness_apply(
+ tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index,
+ const int radius, const int co[2])
{
- bGPDspoint *pt = gps->points + i;
+ bGPDspoint *pt = gps->points + pt_index;
float inf;
/* Compute strength of effect
@@ -294,28 +361,29 @@ static bool gp_brush_thickness_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
/* Make color more or less transparent by the specified amounts */
static bool gp_brush_strength_apply(
- tGP_BrushEditData *gso, bGPDstroke *gps, int i,
+ tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index,
const int radius, const int co[2])
{
- bGPDspoint *pt = gps->points + i;
+ bGPDspoint *pt = gps->points + pt_index;
float inf;
/* Compute strength of effect
- * - We divide the strength by 10, so that users can set "sane" values.
+ * - We divide the strength, 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 = gp_brush_influence_calc(gso, radius, co) / 20.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)) {
- /* make line thinner - reduce stroke pressure */
+ /* make line more transparent - reduce alpha factor */
pt->strength -= inf;
}
else {
- /* make line thicker - increase stroke pressure */
+ /* make line more opaque - increase stroke strength */
pt->strength += inf;
}
+ /* smooth the strength */
+ BKE_gpencil_smooth_stroke_strength(gps, pt_index, inf);
/* Strength should stay within [0.0, 1.0] */
CLAMP(pt->strength, 0.0f, 1.0f);
@@ -382,8 +450,9 @@ 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, int i,
- const int radius, const int co[2])
+static bool gp_brush_grab_store_points(
+ tGP_BrushEditData *gso, bGPDstroke *gps, 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);
@@ -392,7 +461,7 @@ static bool gp_brush_grab_store_points(tGP_BrushEditData *gso, bGPDstroke *gps,
BLI_assert(data->size < data->capacity);
/* insert this point into the set of affected points */
- data->points[data->size] = i;
+ data->points[data->size] = pt_index;
data->weights[data->size] = inf;
data->size++;
@@ -431,7 +500,7 @@ 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, bool parented, float diff_mat[4][4])
+ tGP_BrushEditData *gso, bGPDstroke *gps, float diff_mat[4][4])
{
tGPSB_Grab_StrokeData *data = BLI_ghash_lookup(gso->stroke_customdata, gps);
int i;
@@ -443,23 +512,21 @@ static void gp_brush_grab_apply_cached(
/* adjust the amount of displacement to apply */
mul_v3_v3fl(delta, gso->dvec, data->weights[i]);
- if (!parented) {
- /* apply */
- add_v3_v3(&pt->x, delta);
- }
- else {
- float fpt[3];
- /* apply transformation */
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- /* apply */
- add_v3_v3(fpt, delta);
- copy_v3_v3(&pt->x, fpt);
- /* undo transformation to the init parent position */
- float inverse_diff_mat[4][4];
- invert_m4_m4(inverse_diff_mat, diff_mat);
- mul_m4_v3(inverse_diff_mat, &pt->x);
- }
+ float fpt[3];
+ float save_pt[3];
+ copy_v3_v3(save_pt, &pt->x);
+ /* apply transformation */
+ mul_v3_m4v3(fpt, diff_mat, &pt->x);
+ /* apply */
+ add_v3_v3v3(&pt->x, fpt, delta);
+ /* undo transformation to the init parent position */
+ float inverse_diff_mat[4][4];
+ invert_m4_m4(inverse_diff_mat, diff_mat);
+ mul_m4_v3(inverse_diff_mat, &pt->x);
+
+ /* compute lock axis */
+ gpsculpt_compute_lock_axis(gso, pt, save_pt);
}
}
@@ -480,10 +547,14 @@ 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, int i,
- const int radius, const int co[2])
+static bool gp_brush_push_apply(
+ tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index,
+ const int radius, const int co[2])
{
- bGPDspoint *pt = gps->points + i;
+ 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 delta[3] = {0.0f};
@@ -493,6 +564,9 @@ static bool gp_brush_push_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
/* apply */
add_v3_v3(&pt->x, delta);
+ /* compute lock axis */
+ gpsculpt_compute_lock_axis(gso, pt, save_pt);
+
/* done */
return true;
}
@@ -512,7 +586,8 @@ static void gp_brush_calc_midpoint(tGP_BrushEditData *gso)
float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d)->location;
float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL);
- float mval_f[2] = {UNPACK2(gso->mval)};
+ float mval_f[2];
+ copy_v2fl_v2i(mval_f, gso->mval);
float mval_prj[2];
float dvec[3];
@@ -536,12 +611,15 @@ 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, int i,
- const int radius, const int co[2])
+static bool gp_brush_pinch_apply(
+ tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index,
+ const int radius, const int co[2])
{
- bGPDspoint *pt = gps->points + i;
+ bGPDspoint *pt = gps->points + pt_index;
float fac, inf;
float vec[3];
+ float save_pt[3];
+ copy_v3_v3(save_pt, &pt->x);
/* Scale down standard influence value to get it more manageable...
* - No damping = Unmanageable at > 0.5 strength
@@ -571,6 +649,9 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
/* 3) Translate back to original space, with the shrinkage applied */
add_v3_v3v3(&pt->x, gso->dvec, vec);
+ /* compute lock axis */
+ gpsculpt_compute_lock_axis(gso, pt, save_pt);
+
/* done */
return true;
}
@@ -582,11 +663,14 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
* convert the rotated point and convert it into "data" space
*/
-static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
- const int radius, const int co[2])
+static bool gp_brush_twist_apply(
+ tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index,
+ const int radius, const int co[2])
{
- bGPDspoint *pt = gps->points + i;
+ bGPDspoint *pt = gps->points + pt_index;
float angle, inf;
+ float save_pt[3];
+ copy_v3_v3(save_pt, &pt->x);
/* Angle to rotate by */
inf = gp_brush_influence_calc(gso, radius, co);
@@ -615,6 +699,9 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
sub_v3_v3v3(vec, &pt->x, gso->dvec); /* make relative to center (center is stored in dvec) */
mul_m3_v3(rmat, vec);
add_v3_v3v3(&pt->x, vec, gso->dvec); /* restore */
+
+ /* compute lock axis */
+ gpsculpt_compute_lock_axis(gso, pt, save_pt);
}
else {
const float axis[3] = {0.0f, 0.0f, 1.0f};
@@ -654,10 +741,13 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
/* Randomize Brush */
/* Apply some random jitter to the point */
-static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
- const int radius, const int co[2])
+static bool gp_brush_randomize_apply(
+ tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index,
+ const int radius, const int co[2])
{
- bGPDspoint *pt = gps->points + i;
+ bGPDspoint *pt = gps->points + pt_index;
+ float save_pt[3];
+ copy_v3_v3(save_pt, &pt->x);
/* Amount of jitter to apply depends on the distance of the point to the cursor,
* as well as the strength of the brush
@@ -665,9 +755,11 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
const float inf = gp_brush_influence_calc(gso, radius, co) / 2.0f;
const float fac = BLI_rng_get_float(gso->rng) * inf;
/* need one flag enabled by default */
- if ((gso->settings->flag & (GP_BRUSHEDIT_FLAG_APPLY_POSITION |
- GP_BRUSHEDIT_FLAG_APPLY_STRENGTH |
- GP_BRUSHEDIT_FLAG_APPLY_THICKNESS)) == 0)
+ if ((gso->settings->flag &
+ (GP_BRUSHEDIT_FLAG_APPLY_POSITION |
+ GP_BRUSHEDIT_FLAG_APPLY_STRENGTH |
+ GP_BRUSHEDIT_FLAG_APPLY_THICKNESS |
+ GP_BRUSHEDIT_FLAG_APPLY_UV)) == 0)
{
gso->settings->flag |= GP_BRUSHEDIT_FLAG_APPLY_POSITION;
}
@@ -710,6 +802,8 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
float dvec[3];
ED_view3d_win_to_delta(gso->gsc.ar, svec, dvec, zfac);
add_v3_v3(&pt->x, dvec);
+ /* compute lock axis */
+ gpsculpt_compute_lock_axis(gso, pt, save_pt);
}
}
else {
@@ -749,11 +843,76 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
/* only limit lower value */
CLAMP_MIN(pt->pressure, 0.0f);
}
+ /* apply random to UV (use pressure) */
+ if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_UV) {
+ if (BLI_rng_get_float(gso->rng) > 0.5f) {
+ pt->uv_rot += fac;
+ }
+ else {
+ pt->uv_rot -= fac;
+ }
+ CLAMP(pt->uv_rot, -M_PI_2, M_PI_2);
+ }
/* done */
return true;
}
+/* Weight Paint Brush */
+
+/* Change weight paint for vertex groups */
+static bool gp_brush_weight_apply(
+ tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index,
+ const int radius, const int co[2])
+{
+ bGPDspoint *pt = gps->points + pt_index;
+ MDeformVert *dvert = gps->dvert + pt_index;
+ float inf;
+
+ /* Compute strength of effect
+ * - 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;
+
+ /* need a vertex group */
+ if (gso->vrgroup == -1) {
+ if (gso->object) {
+ BKE_object_defgroup_add(gso->object);
+ gso->vrgroup = 0;
+ }
+ }
+ /* get current weight */
+ float curweight = 0.0f;
+ for (int i = 0; i < dvert->totweight; i++) {
+ MDeformWeight *gpw = &dvert->dw[i];
+ if (gpw->def_nr == gso->vrgroup) {
+ curweight = gpw->weight;
+ break;
+ }
+ }
+
+ if (gp_brush_invert_check(gso)) {
+ /* reduce weight */
+ curweight -= inf;
+ }
+ else {
+ /* increase weight */
+ curweight += inf;
+ }
+
+ CLAMP(curweight, 0.0f, 1.0f);
+ BKE_gpencil_vgroup_add_point_weight(dvert, gso->vrgroup, curweight);
+
+ /* weight should stay within [0.0, 1.0] */
+ if (pt->pressure < 0.0f)
+ pt->pressure = 0.0f;
+
+ return true;
+}
+
+
+
/* ************************************************ */
/* Non Callback-Based Brushes */
@@ -827,7 +986,7 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
/* Init colormap for mapping between the pasted stroke's source colour(names)
* and the final colours that will be used here instead...
*/
- data->new_colors = gp_copybuf_validate_colormap(gso->gpd);
+ data->new_colors = gp_copybuf_validate_colormap(C);
}
/* Free custom data used for "clone" brush */
@@ -857,9 +1016,12 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
{
tGPSB_CloneBrushData *data = gso->customdata;
- Scene *scene = gso->scene;
+ Object *ob = CTX_data_active_object(C);
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, true);
bGPDstroke *gps;
float delta[3];
@@ -882,17 +1044,22 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
new_stroke = MEM_dupallocN(gps);
new_stroke->points = MEM_dupallocN(gps->points);
+ new_stroke->dvert = MEM_dupallocN(gps->dvert);
+ BKE_gpencil_stroke_weights_duplicate(gps, new_stroke);
new_stroke->triangles = MEM_dupallocN(gps->triangles);
new_stroke->next = new_stroke->prev = NULL;
BLI_addtail(&gpf->strokes, new_stroke);
/* Fix color references */
- BLI_assert(new_stroke->colorname[0] != '\0');
- new_stroke->palcolor = BLI_ghash_lookup(data->new_colors, new_stroke->colorname);
-
- BLI_assert(new_stroke->palcolor != NULL);
- BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname));
+ Material *ma = BLI_ghash_lookup(data->new_colors, &new_stroke->mat_nr);
+ if ((ma) && (BKE_gpencil_get_material_index(ob, ma) > 0)) {
+ gps->mat_nr = BKE_gpencil_get_material_index(ob, ma) - 1;
+ CLAMP_MIN(gps->mat_nr, 0);
+ }
+ else {
+ gps->mat_nr = 0; /* only if the color is not found */
+ }
/* Adjust all the stroke's points, so that the strokes
* get pasted relative to where the cursor is now
@@ -977,57 +1144,6 @@ static bool gpsculpt_brush_apply_clone(bContext *C, tGP_BrushEditData *gso)
}
/* ************************************************ */
-/* Cursor drawing */
-
-/* Helper callback for drawing the cursor itself */
-static void gp_brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata))
-{
- GP_EditBrush_Data *brush = gpsculpt_get_brush(CTX_data_scene(C));
-
- if (brush) {
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- GPU_line_smooth(true);
- GPU_blend(true);
-
- /* Inner Ring: Light color for action of the brush */
- /* TODO: toggle between add and remove? */
- immUniformColor4ub(255, 255, 255, 200);
- imm_draw_circle_wire_2d(pos, x, y, brush->size, 40);
-
- /* Outer Ring: Dark color for contrast on light backgrounds (e.g. gray on white) */
- immUniformColor3ub(30, 30, 30);
- imm_draw_circle_wire_2d(pos, x, y, brush->size + 1, 40);
-
- immUnbindProgram();
-
- GPU_blend(false);
- GPU_line_smooth(false);
- }
-}
-
-/* Turn brush cursor in on/off */
-static void gpencil_toggle_brush_cursor(bContext *C, bool enable)
-{
- GP_BrushEdit_Settings *gset = gpsculpt_get_settings(CTX_data_scene(C));
-
- if (gset->paintcursor && !enable) {
- /* clear cursor */
- WM_paint_cursor_end(CTX_wm_manager(C), gset->paintcursor);
- gset->paintcursor = NULL;
- }
- else if (enable) {
- /* enable cursor */
- gset->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C),
- NULL,
- gp_brush_drawcursor, NULL);
- }
-}
-
-
-/* ************************************************ */
/* Header Info for GPencil Sculpt */
static void gpsculpt_brush_header_set(bContext *C, tGP_BrushEditData *gso)
@@ -1054,17 +1170,40 @@ static void gpsculpt_brush_header_set(bContext *C, tGP_BrushEditData *gso)
static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Object *ob = CTX_data_active_object(C);
+
+ const bool is_weight_mode = ob->mode == OB_MODE_GPENCIL_WEIGHT;
+ /* set the brush using the tool */
+ GP_BrushEdit_Settings *gset = &ts->gp_sculpt;
+ eGP_EditBrush_Types mode = RNA_enum_get(op->ptr, "mode");
+ const bool keep_brush = RNA_boolean_get(op->ptr, "keep_brush");
+
+ if (!keep_brush) {
+ if (is_weight_mode) {
+ gset->weighttype = mode;
+ }
+ else {
+ gset->brushtype = mode;
+ }
+ }
tGP_BrushEditData *gso;
/* setup operator data */
gso = MEM_callocN(sizeof(tGP_BrushEditData), "tGP_BrushEditData");
op->customdata = gso;
+ gso->depsgraph = CTX_data_depsgraph(C);
/* store state */
gso->settings = gpsculpt_get_settings(scene);
- gso->brush = gpsculpt_get_brush(scene);
+ gso->brush = gpsculpt_get_brush(scene, is_weight_mode);
- gso->brush_type = gso->settings->brushtype;
+ if (is_weight_mode) {
+ gso->brush_type = gso->settings->weighttype;
+ }
+ else {
+ gso->brush_type = gso->settings->brushtype;
+ }
/* Random generator, only init once. */
uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX);
@@ -1078,10 +1217,31 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
gso->cfra = INT_MAX; /* NOTE: So that first stroke will get handled in init_stroke() */
gso->scene = scene;
+ gso->object = ob;
+ if (ob) {
+ gso->vrgroup = ob->actdef - 1;
+ if (!BLI_findlink(&ob->defbase, gso->vrgroup)) {
+ gso->vrgroup = -1;
+ }
+ }
+ else {
+ gso->vrgroup = - 1;
+ }
gso->sa = CTX_wm_area(C);
gso->ar = CTX_wm_region(C);
+ /* multiframe settings */
+ gso->is_multiframe = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gso->gpd);
+ gso->use_multiframe_falloff = (ts->gp_sculpt.flag & GP_BRUSHEDIT_FLAG_FRAME_FALLOFF) != 0;
+
+ /* init multiedit falloff curve data before doing anything,
+ * so we won't have to do it again later
+ */
+ if (gso->is_multiframe) {
+ curvemapping_initialize(ts->gp_sculpt.cur_falloff);
+ }
+
/* initialise custom data for brushes */
switch (gso->brush_type) {
case GP_EDITBRUSH_TYPE_CLONE:
@@ -1133,9 +1293,10 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
gpsculpt_brush_header_set(C, gso);
/* setup cursor drawing */
- WM_cursor_modal_set(CTX_wm_window(C), BC_CROSSCURSOR);
- gpencil_toggle_brush_cursor(C, true);
-
+ //WM_cursor_modal_set(CTX_wm_window(C), BC_CROSSCURSOR);
+ if (gso->sa->spacetype != SPACE_VIEW3D) {
+ ED_gpencil_toggle_brush_cursor(C, true, NULL);
+ }
return true;
}
@@ -1179,7 +1340,12 @@ static void gpsculpt_brush_exit(bContext *C, wmOperator *op)
/* disable cursor and headerprints */
ED_workspace_status_text(C, NULL);
WM_cursor_modal_restore(win);
- gpencil_toggle_brush_cursor(C, false);
+ if (gso->sa->spacetype != SPACE_VIEW3D) {
+ ED_gpencil_toggle_brush_cursor(C, false, NULL);
+ }
+
+ /* disable temp invert flag */
+ gso->brush->flag &= ~GP_EDITBRUSH_FLAG_TMP_INVERT;
/* free operator data */
MEM_freeN(gso);
@@ -1197,13 +1363,13 @@ static bool gpsculpt_brush_poll(bContext *C)
static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso)
{
- Scene *scene = gso->scene;
bGPdata *gpd = gso->gpd;
+
bGPDlayer *gpl;
- int cfra = CFRA;
+ int cfra_eval = (int)DEG_get_ctime(gso->depsgraph);
/* only try to add a new frame if this is the first stroke, or the frame has changed */
- if ((gpd == NULL) || (cfra == gso->cfra))
+ if ((gpd == NULL) || (cfra_eval == gso->cfra))
return;
/* go through each layer, and ensure that we've got a valid frame to use */
@@ -1217,21 +1383,21 @@ static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso)
* spent too much time editing the wrong frame...
*/
// XXX: should this be allowed when framelock is enabled?
- if (gpf->framenum != cfra) {
- BKE_gpencil_frame_addcopy(gpl, cfra);
+ if (gpf->framenum != cfra_eval) {
+ BKE_gpencil_frame_addcopy(gpl, cfra_eval);
}
}
}
/* save off new current frame, so that next update works fine */
- gso->cfra = cfra;
+ gso->cfra = cfra_eval;
}
/* Apply ----------------------------------------------- */
/* Apply brush operation to points in this stroke */
static bool gpsculpt_brush_do_stroke(
- tGP_BrushEditData *gso, bGPDstroke *gps, bool parented,
+ tGP_BrushEditData *gso, bGPDstroke *gps,
float diff_mat[4][4], GP_BrushApplyCb apply)
{
GP_SpaceConversion *gsc = &gso->gsc;
@@ -1246,14 +1412,9 @@ static bool gpsculpt_brush_do_stroke(
bool changed = false;
if (gps->totpoints == 1) {
- if (!parented) {
- gp_point_to_xy(gsc, gps, gps->points, &pc1[0], &pc1[1]);
- }
- else {
- bGPDspoint pt_temp;
- gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
- gp_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
- }
+ bGPDspoint pt_temp;
+ gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
+ gp_point_to_xy(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])) {
@@ -1280,19 +1441,12 @@ static bool gpsculpt_brush_do_stroke(
continue;
}
}
- if (!parented) {
- gp_point_to_xy(gsc, gps, pt1, &pc1[0], &pc1[1]);
- gp_point_to_xy(gsc, gps, pt2, &pc2[0], &pc2[1]);
- }
- else {
- bGPDspoint npt;
- gp_point_to_parent_space(pt1, diff_mat, &npt);
- gp_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]);
- }
+ bGPDspoint npt;
+ gp_point_to_parent_space(pt1, diff_mat, &npt);
+ gp_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]);
/* 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])) ||
@@ -1342,9 +1496,114 @@ static bool gpsculpt_brush_do_stroke(
return changed;
}
+/* Apply sculpt brushes to strokes in the given frame */
+static bool gpsculpt_brush_do_frame(
+ bContext *C, tGP_BrushEditData *gso,
+ bGPDlayer *gpl, bGPDframe *gpf,
+ float diff_mat[4][4])
+{
+ bool changed = false;
+ Object *ob = CTX_data_active_object(C);
+
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ continue;
+ }
+
+ switch (gso->brush_type) {
+ case GP_EDITBRUSH_TYPE_SMOOTH: /* Smooth strokes */
+ {
+ changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_smooth_apply);
+ break;
+ }
+
+ case GP_EDITBRUSH_TYPE_THICKNESS: /* Adjust stroke thickness */
+ {
+ changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_thickness_apply);
+ break;
+ }
+
+ case GP_EDITBRUSH_TYPE_STRENGTH: /* Adjust stroke color strength */
+ {
+ changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_strength_apply);
+ break;
+ }
+
+ case GP_EDITBRUSH_TYPE_GRAB: /* Grab points */
+ {
+ if (gso->first) {
+ /* First time this brush stroke is being applied:
+ * 1) Prepare data buffers (init/clear) for this stroke
+ * 2) Use the points now under the cursor
+ */
+ gp_brush_grab_stroke_init(gso, gps);
+ changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_grab_store_points);
+ }
+ else {
+ /* Apply effect to the stored points */
+ gp_brush_grab_apply_cached(gso, gps, diff_mat);
+ changed |= true;
+ }
+ break;
+ }
+
+ case GP_EDITBRUSH_TYPE_PUSH: /* Push points */
+ {
+ changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_push_apply);
+ break;
+ }
+
+ case GP_EDITBRUSH_TYPE_PINCH: /* Pinch points */
+ {
+ changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_pinch_apply);
+ break;
+ }
+
+ case GP_EDITBRUSH_TYPE_TWIST: /* Twist points around midpoint */
+ {
+ changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_twist_apply);
+ break;
+ }
+
+ case GP_EDITBRUSH_TYPE_RANDOMIZE: /* Apply jitter */
+ {
+ changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_randomize_apply);
+ break;
+ }
+
+ case GP_EDITBRUSH_TYPE_WEIGHT: /* Adjust vertex group weight */
+ {
+ changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_weight_apply);
+ break;
+ }
+
+
+ default:
+ printf("ERROR: Unknown type of GPencil Sculpt brush - %u\n", gso->brush_type);
+ break;
+ }
+ /* Triangulation must be calculated if changed */
+ if (changed) {
+ gps->flag |= GP_STROKE_RECALC_CACHES;
+ gps->tot_triangles = 0;
+ }
+ }
+
+ return changed;
+}
+
/* Perform two-pass brushes which modify the existing strokes */
static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
{
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C); \
+ Object *obact = gso->object;
+ bGPdata *gpd = gso->gpd;
bool changed = false;
/* Calculate brush-specific data which applies equally to all points */
@@ -1378,104 +1637,53 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
/* Find visible strokes, and perform operations on those if hit */
- float diff_mat[4][4];
- bool parented = false;
-
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
- bGPDframe *gpf = gpl->actframe;
- if (gpf == NULL)
+ /* If no active frame, don't do anything... */
+ if (gpl->actframe == NULL) {
continue;
-
- /* calculate difference matrix if parent object */
- if (gpl->parent != NULL) {
- ED_gpencil_parent_location(gpl, diff_mat);
- parented = true;
- }
- else {
- parented = false;
}
- for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false)
- continue;
- /* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
- continue;
- }
+ /* calculate difference matrix */
+ float diff_mat[4][4];
+ ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat);
- switch (gso->brush_type) {
- case GP_EDITBRUSH_TYPE_SMOOTH: /* Smooth strokes */
- {
- changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_smooth_apply);
- break;
- }
-
- case GP_EDITBRUSH_TYPE_THICKNESS: /* Adjust stroke thickness */
- {
- changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_thickness_apply);
- break;
- }
+ /* Active Frame or MultiFrame? */
+ if (gso->is_multiframe) {
+ /* init multiframe falloff options */
+ int f_init = 0;
+ int f_end = 0;
- case GP_EDITBRUSH_TYPE_STRENGTH: /* Adjust stroke color strength */
- {
- changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_strength_apply);
- break;
- }
+ if (gso->use_multiframe_falloff) {
+ BKE_gpencil_get_range_selected(gpl, &f_init, &f_end);
+ }
- case GP_EDITBRUSH_TYPE_GRAB: /* Grab points */
- {
- if (gso->first) {
- /* First time this brush stroke is being applied:
- * 1) Prepare data buffers (init/clear) for this stroke
- * 2) Use the points now under the cursor
- */
- gp_brush_grab_stroke_init(gso, gps);
- changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_grab_store_points);
+ for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ /* Always do active frame; Otherwise, only include selected frames */
+ if ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)) {
+ /* compute multiframe falloff factor */
+ if (gso->use_multiframe_falloff) {
+ /* Faloff depends on distance to active frame (relative to the overall frame range) */
+ gso->mf_falloff = BKE_gpencil_multiframe_falloff_calc(
+ gpf, gpl->actframe->framenum,
+ f_init, f_end,
+ ts->gp_sculpt.cur_falloff);
}
else {
- /* Apply effect to the stored points */
- gp_brush_grab_apply_cached(gso, gps, parented, diff_mat);
- changed |= true;
+ /* No falloff */
+ gso->mf_falloff = 1.0f;
}
- break;
- }
-
- case GP_EDITBRUSH_TYPE_PUSH: /* Push points */
- {
- changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_push_apply);
- break;
- }
-
- case GP_EDITBRUSH_TYPE_PINCH: /* Pinch points */
- {
- changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_pinch_apply);
- break;
- }
-
- case GP_EDITBRUSH_TYPE_TWIST: /* Twist points around midpoint */
- {
- changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_twist_apply);
- break;
- }
- case GP_EDITBRUSH_TYPE_RANDOMIZE: /* Apply jitter */
- {
- changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_randomize_apply);
- break;
+ /* affect strokes in this frame */
+ changed |= gpsculpt_brush_do_frame(C, gso, gpl, gpf, diff_mat);
}
-
- default:
- printf("ERROR: Unknown type of GPencil Sculpt brush - %u\n", gso->brush_type);
- break;
- }
- /* Triangulation must be calculated if changed */
- if (changed) {
- gps->flag |= GP_STROKE_RECALC_CACHES;
- gps->tot_triangles = 0;
}
}
+ else {
+ /* Apply to active frame's strokes */
+ gso->mf_falloff = 1.0f;
+ changed |= gpsculpt_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
+ }
}
CTX_DATA_END;
@@ -1529,6 +1737,7 @@ static void gpsculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itempt
/* Updates */
if (changed) {
+ DEG_id_tag_update(&gso->gpd->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
@@ -1605,9 +1814,18 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve
{
tGP_BrushEditData *gso = NULL;
const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
+ const bool is_playing = ED_screen_animation_playing(CTX_wm_manager(C)) != NULL;
bool needs_timer = false;
float brush_rate = 0.0f;
+ /* the operator cannot work while play animation */
+ if (is_playing) {
+ BKE_report(op->reports, RPT_ERROR,
+ "Cannot sculpt while play animation");
+
+ return OPERATOR_CANCELLED;
+ }
+
/* init painting data */
if (!gpsculpt_brush_init(C, op))
return OPERATOR_CANCELLED;
@@ -1832,7 +2050,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
case DOWNARROWKEY:
return OPERATOR_PASS_THROUGH;
- /* Camera/View Manipulations - Allowed */
+ /* Camera/View Gizmo's - Allowed */
/* (See rationale in gpencil_paint.c -> gpencil_draw_modal()) */
case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
@@ -1852,6 +2070,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
/* Redraw toolsettings (brush settings)? */
if (redraw_toolsettings) {
+ DEG_id_tag_update(&gso->gpd->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
}
@@ -1860,6 +2079,19 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
/* Operator --------------------------------------------- */
+static const EnumPropertyItem prop_gpencil_sculpt_brush_items[] = {
+ {GP_EDITBRUSH_TYPE_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth stroke points" },
+ {GP_EDITBRUSH_TYPE_THICKNESS, "THICKNESS", 0, "Thickness", "Adjust thickness of strokes" },
+ {GP_EDITBRUSH_TYPE_STRENGTH, "STRENGTH", 0, "Strength", "Adjust color strength of strokes" },
+ {GP_EDITBRUSH_TYPE_GRAB, "GRAB", 0, "Grab", "Translate the set of points initially within the brush circle" },
+ {GP_EDITBRUSH_TYPE_PUSH, "PUSH", 0, "Push", "Move points out of the way, as if combing them" },
+ {GP_EDITBRUSH_TYPE_TWIST, "TWIST", 0, "Twist", "Rotate points around the midpoint of the brush" },
+ {GP_EDITBRUSH_TYPE_PINCH, "PINCH", 0, "Pinch", "Pull points towards the midpoint of the brush" },
+ {GP_EDITBRUSH_TYPE_RANDOMIZE, "RANDOMIZE", 0, "Randomize", "Introduce jitter/randomness into strokes" },
+ {GP_EDITBRUSH_TYPE_CLONE, "CLONE", 0, "Clone", "Paste copies of the strokes stored on the clipboard" },
+ {GP_EDITBRUSH_TYPE_WEIGHT, "WEIGHT", 0, "Weight", "Weight Paint" },
+ {0, NULL, 0, NULL, NULL }
+};
void GPENCIL_OT_brush_paint(wmOperatorType *ot)
{
@@ -1879,13 +2111,20 @@ void GPENCIL_OT_brush_paint(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
/* properties */
+ ot->prop = RNA_def_enum(ot->srna, "mode", prop_gpencil_sculpt_brush_items, 0, "Mode", "Brush mode");
+ RNA_def_property_flag(ot->prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+
PropertyRNA *prop;
prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input",
"Enter a mini 'sculpt-mode' if enabled, otherwise, exit after drawing a single stroke");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(ot->srna, "keep_brush", false, "Keep Brush",
+ "Keep current brush activated");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
/* ************************************************ */
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index ccdbcba71f9..f662e9b42be 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -56,7 +56,6 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_gpencil_types.h"
-#include "DNA_workspace_types.h"
#include "BKE_collection.h"
#include "BKE_context.h"
@@ -74,6 +73,7 @@
#include "BKE_tracking.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "UI_interface.h"
@@ -149,28 +149,24 @@ static const EnumPropertyItem *rna_GPConvert_mode_items(bContext *UNUSED(C), Poi
* - assumes that the active space is the 3D-View
*/
static void gp_strokepoint_convertcoords(
- bContext *C, bGPDlayer *gpl, bGPDstroke *gps, bGPDspoint *source_pt,
+ bContext *C, bGPdata *gpd, 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);
ARegion *ar = CTX_wm_region(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C); \
+ Object *obact = CTX_data_active_object(C);
bGPDspoint mypt, *pt;
float diff_mat[4][4];
pt = &mypt;
- /* calculate difference matrix if parent object */
- if (gpl->parent == NULL) {
- copy_v3_v3(&pt->x, &source_pt->x);
- }
- else {
- /* apply parent transform */
- float fpt[3];
- ED_gpencil_parent_location(gpl, diff_mat);
- mul_v3_m4v3(fpt, diff_mat, &source_pt->x);
- copy_v3_v3(&pt->x, fpt);
- }
+ /* apply parent transform */
+ float fpt[3];
+ ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat);
+ mul_v3_m4v3(fpt, diff_mat, &source_pt->x);
+ copy_v3_v3(&pt->x, fpt);
if (gps->flag & GP_STROKE_3DSPACE) {
@@ -591,7 +587,7 @@ static void gp_stroke_to_path_add_point(tGpTimingData *gtd, BPoint *bp, const fl
}
}
-static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu,
+static void gp_stroke_to_path(bContext *C, bGPdata *gpd, 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)
{
@@ -655,7 +651,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
bp = &nu->bp[old_nbp - 1];
/* First point */
- gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
+ gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points, p, subrect);
if (prev_bp) {
interp_v3_v3v3(p1, bp->vec, prev_bp->vec, -GAP_DFAC);
if (do_gtd) {
@@ -676,7 +672,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
/* 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);
+ gp_strokepoint_convertcoords(C, gpd, 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);
@@ -697,9 +693,9 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
float p[3], next_p[3];
float dt = 0.0f;
- gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
+ gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points, p, subrect);
if (gps->totpoints > 1) {
- gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect);
+ gp_strokepoint_convertcoords(C, gpd, 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);
@@ -728,10 +724,10 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
i++, pt++, bp++)
{
float p[3];
- float width = pt->pressure * (gps->thickness + gpl->thickness) * WIDTH_CORR_FAC;
+ 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_strokepoint_convertcoords(C, gpd, 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);
@@ -801,7 +797,7 @@ static void gp_stroke_to_bezier_add_point(tGpTimingData *gtd, BezTriple *bezt,
}
}
-static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu,
+static void gp_stroke_to_bezier(bContext *C, bGPdata *gpd, 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)
{
@@ -843,12 +839,12 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
/* get initial coordinates */
pt = gps->points;
if (tot) {
- gp_strokepoint_convertcoords(C, gpl, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect);
+ gp_strokepoint_convertcoords(C, gpd, 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);
+ gp_strokepoint_convertcoords(C, gpd, 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);
+ gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt + 2, p3d_next, subrect);
}
}
@@ -967,7 +963,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
/* add points */
for (i = stitch ? 1 : 0, bezt = &nu->bezt[old_nbezt]; i < tot; i++, pt++, bezt++) {
- float width = pt->pressure * (gps->thickness + gpl->thickness) * WIDTH_CORR_FAC;
+ float width = pt->pressure * (gps->thickness + gpl->line_change) * WIDTH_CORR_FAC;
if (i || old_nbezt) {
interp_v3_v3v3(h1, p3d_cur, p3d_prev, BEZT_HANDLE_FAC);
@@ -991,7 +987,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
copy_v3_v3(p3d_cur, p3d_next);
if (i + 2 < tot) {
- gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect);
+ gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt + 2, p3d_next, subrect);
}
prev_bezt = bezt;
@@ -1130,10 +1126,12 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
const bool norm_weights, const float rad_fac, const bool link_strokes, tGpTimingData *gtd)
{
struct Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Collection *collection = CTX_data_collection(C);
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0);
bGPDstroke *gps, *prev_gps = NULL;
Object *ob;
Curve *cu;
@@ -1192,12 +1190,12 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
switch (mode) {
case GP_STROKECONVERT_PATH:
- gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch,
+ gp_stroke_to_path(C, gpd, 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,
+ gp_stroke_to_bezier(C, gpd, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch,
add_start_point, add_end_point, gtd);
break;
default:
@@ -1238,7 +1236,9 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
*/
static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
bGPDframe *gpf = NULL;
bGPDstroke *gps = NULL;
bGPDspoint *pt;
@@ -1246,7 +1246,7 @@ static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOpe
int i;
bool valid = true;
- if (!gpl || !(gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0)) || !(gps = gpf->strokes.first))
+ if (!gpl || !(gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0)) || !(gps = gpf->strokes.first))
return false;
do {
@@ -1294,10 +1294,12 @@ static void gp_convert_set_end_frame(struct Main *UNUSED(main), struct Scene *UN
static bool gp_convert_poll(bContext *C)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
bGPDlayer *gpl = NULL;
bGPDframe *gpf = NULL;
ScrArea *sa = CTX_wm_area(C);
- Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
/* only if the current view is 3D View, if there's valid data (i.e. at least one stroke!),
@@ -1305,7 +1307,7 @@ static bool gp_convert_poll(bContext *C)
*/
return ((sa && sa->spacetype == SPACE_VIEW3D) &&
(gpl = BKE_gpencil_layer_getactive(gpd)) &&
- (gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0)) &&
+ (gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0)) &&
(gpf->strokes.first) &&
(OBEDIT_FROM_VIEW_LAYER(view_layer) == NULL));
}
@@ -1382,8 +1384,9 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+static bool gp_convert_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
{
+ PointerRNA *ptr = op->ptr;
const char *prop_id = RNA_property_identifier(prop);
const bool link_strokes = RNA_boolean_get(ptr, "use_link_strokes");
int timing_mode = RNA_enum_get(ptr, "timing_mode");
@@ -1446,18 +1449,6 @@ static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
return false;
}
-static void gp_convert_ui(bContext *C, wmOperator *op)
-{
- uiLayout *layout = op->layout;
- wmWindowManager *wm = CTX_wm_manager(C);
- PointerRNA ptr;
-
- RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-
- /* Main auto-draw call */
- uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
-}
-
void GPENCIL_OT_convert(wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -1471,7 +1462,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
ot->invoke = WM_menu_invoke;
ot->exec = gp_convert_layer_exec;
ot->poll = gp_convert_poll;
- ot->ui = gp_convert_ui;
+ ot->poll_property = gp_convert_poll_property;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index c28fea0fc41..faeee4db169 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -46,18 +46,31 @@
#include "BLT_translation.h"
+#include "DNA_anim_types.h"
+#include "DNA_brush_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_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_gpencil_types.h"
-#include "BKE_colortools.h"
+#include "BKE_main.h"
+#include "BKE_brush.h"
+#include "BKE_animsys.h"
#include "BKE_context.h"
+#include "BKE_deform.h"
+#include "BKE_fcurve.h"
+#include "BKE_global.h"
#include "BKE_gpencil.h"
+#include "BKE_gpencil_modifier.h"
#include "BKE_library.h"
-#include "BKE_main.h"
+#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_material.h"
+#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
@@ -72,8 +85,13 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
+#include "ED_object.h"
#include "ED_gpencil.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
+
#include "gpencil_intern.h"
/* ************************************************ */
@@ -84,9 +102,9 @@
/* add new datablock - wrapper around API */
static int gp_data_add_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
- ToolSettings *ts = CTX_data_tool_settings(C);
+ PointerRNA gpd_owner = {{NULL}};
+ bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, &gpd_owner);
+ bool is_annotation = ED_gpencil_data_owner_is_annotation(&gpd_owner);
if (gpd_ptr == NULL) {
BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
@@ -94,19 +112,36 @@ static int gp_data_add_exec(bContext *C, wmOperator *op)
}
else {
/* decrement user count and add new datablock */
- bGPdata *gpd = (*gpd_ptr);
+ /* TODO: if a datablock exists, we should make a copy of it instead of starting fresh (as in other areas) */
+ Main *bmain = CTX_data_main(C);
- id_us_min(&gpd->id);
- *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil"));
+ /* decrement user count of old GP datablock */
+ if (*gpd_ptr) {
+ bGPdata *gpd = (*gpd_ptr);
+ id_us_min(&gpd->id);
+ }
- /* if not exist brushes, create a new set */
- if (ts) {
- if (BLI_listbase_is_empty(&ts->gp_brushes)) {
- /* create new brushes */
- BKE_gpencil_brush_init_presets(ts);
- }
+ /* add new datablock, with a single layer ready to use (so users don't have to perform an extra step) */
+ if (is_annotation) {
+ bGPdata *gpd = BKE_gpencil_data_addnew(bmain, DATA_("Annotations"));
+ *gpd_ptr = gpd;
+
+ /* tag for annotations */
+ gpd->flag |= GP_DATA_ANNOTATIONS;
+
+ /* add new layer (i.e. a "note") */
+ BKE_gpencil_layer_addnew(*gpd_ptr, DATA_("Note"), true);
}
+ else {
+ /* GP Object Case - This shouldn't happen! */
+ *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil"));
+
+ /* add default sets of colors and brushes */
+ ED_gpencil_add_defaults(C);
+ /* add new layer */
+ BKE_gpencil_layer_addnew(*gpd_ptr, DATA_("GP_Layer"), true);
+ }
}
/* notifiers */
@@ -185,28 +220,42 @@ void GPENCIL_OT_data_unlink(wmOperatorType *ot)
/* add new layer - wrapper around API */
static int gp_layer_add_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
- ToolSettings *ts = CTX_data_tool_settings(C);
+ PointerRNA gpd_owner = {{NULL}};
+ bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, &gpd_owner);
+ bool is_annotation = ED_gpencil_data_owner_is_annotation(&gpd_owner);
/* if there's no existing Grease-Pencil data there, add some */
if (gpd_ptr == NULL) {
BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
return OPERATOR_CANCELLED;
}
- if (*gpd_ptr == NULL)
- *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil"));
- /* if not exist brushes, create a new set */
- if (ts) {
- if (BLI_listbase_is_empty(&ts->gp_brushes)) {
- /* create new brushes */
- BKE_gpencil_brush_init_presets(ts);
+ if (*gpd_ptr == NULL) {
+ Main *bmain = CTX_data_main(C);
+ if (is_annotation) {
+ /* Annotations */
+ *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("Annotations"));
+
+ /* mark as annotation */
+ (*gpd_ptr)->flag |= GP_DATA_ANNOTATIONS;
+ }
+ else {
+ /* GP Object */
+ /* NOTE: This shouldn't actually happen in practice */
+ *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil"));
+
+ /* add default sets of colors and brushes */
+ ED_gpencil_add_defaults(C);
}
}
/* add new layer now */
- BKE_gpencil_layer_addnew(*gpd_ptr, DATA_("GP_Layer"), true);
+ if (is_annotation) {
+ BKE_gpencil_layer_addnew(*gpd_ptr, DATA_("Note"), true);
+ }
+ else {
+ BKE_gpencil_layer_addnew(*gpd_ptr, DATA_("GP_Layer"), true);
+ }
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
@@ -219,7 +268,7 @@ void GPENCIL_OT_layer_add(wmOperatorType *ot)
/* identifiers */
ot->name = "Add New Layer";
ot->idname = "GPENCIL_OT_layer_add";
- ot->description = "Add new Grease Pencil layer for the active Grease Pencil data-block";
+ ot->description = "Add new layer or note for the active data-block";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -257,6 +306,7 @@ static int gp_layer_remove_exec(bContext *C, wmOperator *op)
BKE_gpencil_layer_delete(gpd, gpl);
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -296,6 +346,7 @@ static int gp_layer_move_exec(bContext *C, wmOperator *op)
BLI_assert(ELEM(direction, -1, 0, 1)); /* we use value below */
if (BLI_listbase_link_move(&gpd->layers, gpl, direction)) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
@@ -346,6 +397,7 @@ static int gp_layer_copy_exec(bContext *C, wmOperator *UNUSED(op))
BKE_gpencil_layer_setactive(gpd, new_layer);
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -366,6 +418,153 @@ void GPENCIL_OT_layer_duplicate(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/* ********************* Duplicate Frame ************************** */
+enum {
+ GP_FRAME_DUP_ACTIVE = 0,
+ GP_FRAME_DUP_ALL = 1
+};
+
+static int gp_frame_duplicate_exec(bContext *C, wmOperator *op)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
+ int mode = RNA_enum_get(op->ptr, "mode");
+
+ /* sanity checks */
+ if (ELEM(NULL, gpd, gpl))
+ return OPERATOR_CANCELLED;
+
+ if (mode == 0) {
+ BKE_gpencil_frame_addcopy(gpl, cfra_eval);
+ }
+ else {
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ if ((gpl->flag & GP_LAYER_LOCKED) == 0) {
+ BKE_gpencil_frame_addcopy(gpl, cfra_eval);
+ }
+ }
+
+ }
+ /* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_frame_duplicate(wmOperatorType *ot)
+{
+ static const EnumPropertyItem duplicate_mode[] = {
+ { GP_FRAME_DUP_ACTIVE, "ACTIVE", 0, "Active", "Duplicate frame in active layer only" },
+ { GP_FRAME_DUP_ALL, "ALL", 0, "All", "Duplicate active frames in all layers" },
+ { 0, NULL, 0, NULL, NULL }
+ };
+
+ /* identifiers */
+ ot->name = "Duplicate Frame";
+ ot->idname = "GPENCIL_OT_frame_duplicate";
+ ot->description = "Make a copy of the active Grease Pencil Frame";
+
+ /* callbacks */
+ ot->exec = gp_frame_duplicate_exec;
+ ot->poll = gp_active_layer_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_enum(ot->srna, "mode", duplicate_mode, GP_FRAME_DUP_ACTIVE, "Mode", "");
+}
+
+/* ********************* Clean Fill Boundaries on Frame ************************** */
+enum {
+ GP_FRAME_CLEAN_FILL_ACTIVE = 0,
+ GP_FRAME_CLEAN_FILL_ALL = 1
+};
+
+static int gp_frame_clean_fill_exec(bContext *C, wmOperator *op)
+{
+ bool changed = false;
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ int mode = RNA_enum_get(op->ptr, "mode");
+
+ CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+ {
+ bGPDframe *init_gpf = gpl->actframe;
+ if (mode == GP_FRAME_CLEAN_FILL_ALL) {
+ init_gpf = gpl->frames.first;
+ }
+
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || (mode == GP_FRAME_CLEAN_FILL_ALL)) {
+ bGPDstroke *gps, *gpsn;
+
+ if (gpf == NULL)
+ continue;
+
+ /* simply delete strokes which are no fill */
+ for (gps = gpf->strokes.first; gps; gps = gpsn) {
+ gpsn = gps->next;
+
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
+
+ /* free stroke */
+ if (gps->flag & GP_STROKE_NOFILL) {
+ /* free stroke memory arrays, then stroke itself */
+ if (gps->points) {
+ MEM_freeN(gps->points);
+ }
+ if (gps->dvert) {
+ BKE_gpencil_free_stroke_weights(gps);
+ MEM_freeN(gps->dvert);
+ }
+ MEM_SAFE_FREE(gps->triangles);
+ BLI_freelinkN(&gpf->strokes, gps);
+
+ changed = true;
+ }
+ }
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ /* notifiers */
+ if (changed) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_frame_clean_fill(wmOperatorType *ot)
+{
+ static const EnumPropertyItem duplicate_mode[] = {
+ { GP_FRAME_CLEAN_FILL_ACTIVE, "ACTIVE", 0, "Active Frame Only", "Clean active frame only" },
+ { GP_FRAME_CLEAN_FILL_ALL, "ALL", 0, "All Frames", "Clean all frames in all layers" },
+ { 0, NULL, 0, NULL, NULL }
+ };
+
+ /* identifiers */
+ ot->name = "Clean Fill Boundaries";
+ ot->idname = "GPENCIL_OT_frame_clean_fill";
+ ot->description = "Remove 'no fill' boundary strokes";
+
+ /* callbacks */
+ ot->exec = gp_frame_clean_fill_exec;
+ ot->poll = gp_active_layer_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_enum(ot->srna, "mode", duplicate_mode, GP_FRAME_DUP_ACTIVE, "Mode", "");
+}
+
/* *********************** Hide Layers ******************************** */
static int gp_hide_exec(bContext *C, wmOperator *op)
@@ -394,6 +593,7 @@ static int gp_hide_exec(bContext *C, wmOperator *op)
}
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -481,6 +681,7 @@ static int gp_reveal_exec(bContext *C, wmOperator *op)
}
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -521,6 +722,7 @@ static int gp_lock_all_exec(bContext *C, wmOperator *UNUSED(op))
}
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -558,6 +760,7 @@ static int gp_unlock_all_exec(bContext *C, wmOperator *UNUSED(op))
}
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -630,6 +833,7 @@ static int gp_isolate_layer_exec(bContext *C, wmOperator *op)
}
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -673,22 +877,28 @@ static int gp_merge_layer_exec(bContext *C, wmOperator *op)
BLI_ghash_insert(gh_frames_cur, SET_INT_IN_POINTER(gpf->framenum), gpf);
}
- /* read all frames from next layer */
+ /* read all frames from next layer and add any missing in current layer */
for (bGPDframe *gpf = gpl_next->frames.first; gpf; gpf = gpf->next) {
- /* try to find frame in active layer */
+ /* try to find frame in current layer */
bGPDframe *frame = BLI_ghash_lookup(gh_frames_cur, SET_INT_IN_POINTER(gpf->framenum));
if (!frame) {
- /* nothing found, create new */
+ bGPDframe *actframe = BKE_gpencil_layer_getframe(gpl_current, gpf->framenum, GP_GETFRAME_USE_PREV);
frame = BKE_gpencil_frame_addnew(gpl_current, gpf->framenum);
+ /* duplicate strokes of current active frame */
+ if (actframe) {
+ BKE_gpencil_frame_copy_strokes(actframe, frame);
+ }
}
/* add to tail all strokes */
BLI_movelisttolist(&frame->strokes, &gpf->strokes);
}
+
/* Now delete next layer */
BKE_gpencil_layer_delete(gpd, gpl_next);
BLI_ghash_free(gh_frames_cur, NULL, NULL);
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -750,6 +960,7 @@ static int gp_layer_change_exec(bContext *C, wmOperator *op)
BKE_gpencil_layer_setactive(gpd, gpl);
/* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -788,6 +999,7 @@ enum {
static int gp_stroke_arrange_exec(bContext *C, wmOperator *op)
{
+ Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
bGPDstroke *gps;
@@ -797,79 +1009,95 @@ static int gp_stroke_arrange_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- bGPDframe *gpf = gpl->actframe;
- /* temp listbase to store selected strokes */
- ListBase selected = {NULL};
const int direction = RNA_enum_get(op->ptr, "direction");
- /* verify if any selected stroke is in the extreme of the stack and select to move */
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
- /* only if selected */
- if (gps->flag & GP_STROKE_SELECT) {
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false) {
- continue;
- }
- /* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
- continue;
- }
- /* some stroke is already at front*/
- if ((direction == GP_STROKE_MOVE_TOP) || (direction == GP_STROKE_MOVE_UP)) {
- if (gps == gpf->strokes.last) {
- return OPERATOR_CANCELLED;
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ /* temp listbase to store selected strokes by layer */
+ ListBase selected = { NULL };
+ bGPDframe *gpf = gpl->actframe;
+ if (gpl->flag & GP_LAYER_LOCKED) {
+ continue;
+ }
+
+ if (gpf == NULL) {
+ continue;
+ }
+ bool gpf_lock = false;
+ /* verify if any selected stroke is in the extreme of the stack and select to move */
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* only if selected */
+ if (gps->flag & GP_STROKE_SELECT) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
}
- }
- /* some stroke is already at botom */
- if ((direction == GP_STROKE_MOVE_BOTTOM) || (direction == GP_STROKE_MOVE_DOWN)) {
- if (gps == gpf->strokes.first) {
- return OPERATOR_CANCELLED;
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ continue;
+ }
+ /* some stroke is already at front*/
+ if ((direction == GP_STROKE_MOVE_TOP) || (direction == GP_STROKE_MOVE_UP)) {
+ if (gps == gpf->strokes.last) {
+ gpf_lock = true;
+ continue;
+ }
+ }
+ /* some stroke is already at botom */
+ if ((direction == GP_STROKE_MOVE_BOTTOM) || (direction == GP_STROKE_MOVE_DOWN)) {
+ if (gps == gpf->strokes.first) {
+ gpf_lock = true;
+ continue;
+ }
+ }
+ /* add to list (if not locked) */
+ if (!gpf_lock) {
+ BLI_addtail(&selected, BLI_genericNodeN(gps));
}
}
- /* add to list */
- BLI_addtail(&selected, BLI_genericNodeN(gps));
}
- }
-
- /* Now do the movement of the stroke */
- switch (direction) {
- /* Bring to Front */
- case GP_STROKE_MOVE_TOP:
- for (LinkData *link = selected.first; link; link = link->next) {
- gps = link->data;
- BLI_remlink(&gpf->strokes, gps);
- BLI_addtail(&gpf->strokes, gps);
- }
- break;
- /* Bring Forward */
- case GP_STROKE_MOVE_UP:
- for (LinkData *link = selected.last; link; link = link->prev) {
- gps = link->data;
- BLI_listbase_link_move(&gpf->strokes, gps, 1);
- }
- break;
- /* Send Backward */
- case GP_STROKE_MOVE_DOWN:
- for (LinkData *link = selected.first; link; link = link->next) {
- gps = link->data;
- BLI_listbase_link_move(&gpf->strokes, gps, -1);
- }
- break;
- /* Send to Back */
- case GP_STROKE_MOVE_BOTTOM:
- for (LinkData *link = selected.last; link; link = link->prev) {
- gps = link->data;
- BLI_remlink(&gpf->strokes, gps);
- BLI_addhead(&gpf->strokes, gps);
+ /* Now do the movement of the stroke */
+ if (!gpf_lock) {
+ switch (direction) {
+ /* Bring to Front */
+ case GP_STROKE_MOVE_TOP:
+ for (LinkData *link = selected.first; link; link = link->next) {
+ gps = link->data;
+ BLI_remlink(&gpf->strokes, gps);
+ BLI_addtail(&gpf->strokes, gps);
+ }
+ break;
+ /* Bring Forward */
+ case GP_STROKE_MOVE_UP:
+ for (LinkData *link = selected.last; link; link = link->prev) {
+ gps = link->data;
+ BLI_listbase_link_move(&gpf->strokes, gps, 1);
+ }
+ break;
+ /* Send Backward */
+ case GP_STROKE_MOVE_DOWN:
+ for (LinkData *link = selected.first; link; link = link->next) {
+ gps = link->data;
+ BLI_listbase_link_move(&gpf->strokes, gps, -1);
+ }
+ break;
+ /* Send to Back */
+ case GP_STROKE_MOVE_BOTTOM:
+ for (LinkData *link = selected.last; link; link = link->prev) {
+ gps = link->data;
+ BLI_remlink(&gpf->strokes, gps);
+ BLI_addhead(&gpf->strokes, gps);
+ }
+ break;
+ default:
+ BLI_assert(0);
+ break;
}
- break;
- default:
- BLI_assert(0);
- break;
+ }
+ BLI_freelistN(&selected);
}
- BLI_freelistN(&selected);
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -890,58 +1118,87 @@ void GPENCIL_OT_stroke_arrange(wmOperatorType *ot)
ot->idname = "GPENCIL_OT_stroke_arrange";
ot->description = "Arrange selected strokes up/down in the drawing order of the active layer";
- /* api callbacks */
+ /* callbacks */
ot->exec = gp_stroke_arrange_exec;
ot->poll = gp_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* properties */
ot->prop = RNA_def_enum(ot->srna, "direction", slot_move, GP_STROKE_MOVE_UP, "Direction", "");
}
+
/* ******************* Move Stroke to new color ************************** */
-static int gp_stroke_change_color_exec(bContext *C, wmOperator *UNUSED(op))
+static int gp_stroke_change_color_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
+ Material *ma = NULL;
+ char name[MAX_ID_NAME - 2];
+ RNA_string_get(op->ptr, "material", name);
+
bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette;
- bGPDpalettecolor *color;
+ Object *ob = CTX_data_active_object(C);
+ if (name[0] == '\0') {
+ ma = give_current_material(ob, ob->actcol);
+ }
+ else {
+ ma = (Material *)BKE_libblock_find_name(bmain, ID_MA, name);
+ if (ma == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+ }
+ /* try to find slot */
+ int idx = BKE_gpencil_get_material_index(ob, ma) - 1;
+ if (idx <= 0) {
+ return OPERATOR_CANCELLED;
+ }
/* sanity checks */
if (ELEM(NULL, gpd)) {
return OPERATOR_CANCELLED;
}
- palette = BKE_gpencil_palette_getactive(gpd);
- color = BKE_gpencil_palettecolor_getactive(palette);
- if (ELEM(NULL, palette, color)) {
+ bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ if (ELEM(NULL, ma)) {
return OPERATOR_CANCELLED;
}
/* loop all strokes */
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- /* only editable and visible layers are considered */
- if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
- for (bGPDstroke *gps = gpl->actframe->strokes.last; gps; gps = gps->prev) {
- /* only if selected */
- if (gps->flag & GP_STROKE_SELECT) {
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false)
- continue;
- /* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false)
- continue;
+ CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+ {
+ bGPDframe *init_gpf = gpl->actframe;
+ if (is_multiedit) {
+ init_gpf = gpl->frames.first;
+ }
+
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (gpf == NULL)
+ continue;
- /* asign new color (only if different) */
- if ((STREQ(gps->colorname, color->info) == false) || (gps->palcolor != color)) {
- BLI_strncpy(gps->colorname, color->info, sizeof(gps->colorname));
- gps->palcolor = color;
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* only if selected */
+ if (gps->flag & GP_STROKE_SELECT) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false)
+ continue;
+
+ /* asign new color */
+ gps->mat_nr = idx;
}
}
}
}
}
+ CTX_DATA_END;
+
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -952,11 +1209,17 @@ void GPENCIL_OT_stroke_change_color(wmOperatorType *ot)
/* identifiers */
ot->name = "Change Stroke Color";
ot->idname = "GPENCIL_OT_stroke_change_color";
- ot->description = "Move selected strokes to active color";
+ ot->description = "Move selected strokes to active material";
- /* api callbacks */
+ /* callbacks */
ot->exec = gp_stroke_change_color_exec;
ot->poll = gp_active_layer_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_string(ot->srna, "material", NULL, MAX_ID_NAME - 2, "Material", "Name of the material");
+
}
/* ******************* Lock color of non selected Strokes colors ************************** */
@@ -964,19 +1227,19 @@ void GPENCIL_OT_stroke_change_color(wmOperatorType *ot)
static int gp_stroke_lock_color_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette;
+
+ Object *ob = CTX_data_active_object(C);
+
+ short *totcol = give_totcolp(ob);
/* sanity checks */
if (ELEM(NULL, gpd))
return OPERATOR_CANCELLED;
- palette = BKE_gpencil_palette_getactive(gpd);
- if (ELEM(NULL, palette))
- return OPERATOR_CANCELLED;
-
/* first lock all colors */
- for (bGPDpalettecolor *palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
- palcolor->flag |= PC_COLOR_LOCKED;
+ for (short i = 0; i < *totcol; i++) {
+ Material *tmp_ma = give_current_material(ob, i + 1);
+ tmp_ma->gp_style->flag |= GP_STYLE_COLOR_LOCKED;
}
/* loop all selected strokes and unlock any color */
@@ -991,14 +1254,15 @@ static int gp_stroke_lock_color_exec(bContext *C, wmOperator *UNUSED(op))
continue;
}
/* unlock color */
- if (gps->palcolor != NULL) {
- gps->palcolor->flag &= ~PC_COLOR_LOCKED;
- }
+ Material *tmp_ma = give_current_material(ob, gps->mat_nr + 1);
+
+ tmp_ma->gp_style->flag &= ~GP_STYLE_COLOR_LOCKED;
}
}
}
}
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -1014,25 +1278,18 @@ void GPENCIL_OT_stroke_lock_color(wmOperatorType *ot)
/* api callbacks */
ot->exec = gp_stroke_lock_color_exec;
ot->poll = gp_active_layer_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************************************ */
/* Drawing Brushes Operators */
-/* ******************* Add New Brush ************************ */
-
-/* add new brush - wrapper around API */
-static int gp_brush_add_exec(bContext *C, wmOperator *op)
+/* ******************* Brush create presets ************************** */
+static int gp_brush_presets_create_exec(bContext *C, wmOperator *UNUSED(op))
{
- ToolSettings *ts = CTX_data_tool_settings(C);
-
- /* if there's no existing container */
- if (ts == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Nowhere for brush data to go");
- return OPERATOR_CANCELLED;
- }
- /* add new brush now */
- BKE_gpencil_brush_addnew(ts, DATA_("GP_Brush"), true);
+ BKE_brush_gpencil_presets(C);
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
@@ -1040,513 +1297,757 @@ static int gp_brush_add_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_brush_add(wmOperatorType *ot)
+void GPENCIL_OT_brush_presets_create(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Add Brush";
- ot->idname = "GPENCIL_OT_brush_add";
- ot->description = "Add new Grease Pencil drawing brush for the active Grease Pencil data-block";
+ ot->name = "Create Preset Brushes";
+ ot->idname = "GPENCIL_OT_brush_presets_create";
+ ot->description = "Create a set of predefined Grease Pencil drawing brushes";
+ /* api callbacks */
+ ot->exec = gp_brush_presets_create_exec;
+
+ /* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* callbacks */
- ot->exec = gp_brush_add_exec;
- ot->poll = gp_add_poll;
}
-/* ******************* Remove Active Brush ************************* */
+/* ***************** Select Brush ************************ */
-static int gp_brush_remove_exec(bContext *C, wmOperator *op)
+static int gp_brush_select_exec(bContext *C, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
- bGPDbrush *brush = BKE_gpencil_brush_getactive(ts);
-
- /* sanity checks */
- if (ELEM(NULL, ts, brush))
- return OPERATOR_CANCELLED;
+ Main *bmain = CTX_data_main(C);
- if (BLI_listbase_count_at_most(&ts->gp_brushes, 2) < 2) {
- BKE_report(op->reports, RPT_ERROR, "Grease Pencil needs a brush, unable to delete the last one");
+ /* if there's no existing container */
+ if (ts == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Nowhere to go");
return OPERATOR_CANCELLED;
}
+ const int index = RNA_int_get(op->ptr, "index");
- /* make the brush before this the new active brush
- * - use the one after if this is the first
- * - if this is the only brush, this naturally becomes NULL
- */
- if (brush->prev)
- BKE_gpencil_brush_setactive(ts, brush->prev);
- else
- BKE_gpencil_brush_setactive(ts, brush->next);
-
- /* delete the brush now... */
- BKE_gpencil_brush_delete(ts, brush);
+ Paint *paint = BKE_brush_get_gpencil_paint(ts);
+ int i = 0;
+ for (Brush *brush = bmain->brush.first; brush; brush = brush->id.next) {
+ if (brush->ob_mode == OB_MODE_GPENCIL_PAINT) {
+ if (i == index) {
+ BKE_paint_brush_set(paint, brush);
- /* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ /* notifiers */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ return OPERATOR_FINISHED;
+ }
+ i++;
+ }
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_CANCELLED;
}
-void GPENCIL_OT_brush_remove(wmOperatorType *ot)
+void GPENCIL_OT_brush_select(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Remove Brush";
- ot->idname = "GPENCIL_OT_brush_remove";
- ot->description = "Remove active Grease Pencil drawing brush";
-
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->name = "Select Brush";
+ ot->idname = "GPENCIL_OT_brush_select";
+ ot->description = "Select a Grease Pencil drawing brush";
/* callbacks */
- ot->exec = gp_brush_remove_exec;
+ ot->exec = gp_brush_select_exec;
ot->poll = gp_active_brush_poll;
-}
-
-/* ********************** Change Brush ***************************** */
-static int gp_brush_change_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(evt))
-{
- uiPopupMenu *pup;
- uiLayout *layout;
-
- /* call the menu, which will call this operator again, hence the canceled */
- pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
- layout = UI_popup_menu_layout(pup);
- uiItemsEnumO(layout, "GPENCIL_OT_brush_change", "brush");
- UI_popup_menu_end(C, pup);
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- return OPERATOR_INTERFACE;
+ /* properties */
+ RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of Drawing Brush", 0, INT_MAX);
}
-static int gp_brush_change_exec(bContext *C, wmOperator *op)
+/* ***************** Select Sculpt Brush ************************ */
+
+static int gp_sculpt_select_exec(bContext *C, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
- bGPDbrush *brush = NULL;
- int brush_num = RNA_enum_get(op->ptr, "brush");
- /* Get brush or create new one */
- if (brush_num == -1) {
- /* Create brush */
- brush = BKE_gpencil_brush_addnew(ts, DATA_("GP_Brush"), true);
+ /* if there's no existing container */
+ if (ts == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Nowhere to go");
+ return OPERATOR_CANCELLED;
}
- else {
- /* Try to get brush */
- brush = BLI_findlink(&ts->gp_brushes, brush_num);
- if (brush == NULL) {
- BKE_reportf(op->reports, RPT_ERROR, "Cannot change to non-existent brush (index = %d)", brush_num);
- return OPERATOR_CANCELLED;
- }
+ const int index = RNA_int_get(op->ptr, "index");
+ GP_BrushEdit_Settings *gp_sculpt = &ts->gp_sculpt;
+ /* sanity checks */
+ if (ELEM(NULL, gp_sculpt)) {
+ return OPERATOR_CANCELLED;
}
- /* Set active brush */
- BKE_gpencil_brush_setactive(ts, brush);
-
- /* updates */
+ if (index < TOT_GP_EDITBRUSH_TYPES - 1) {
+ gp_sculpt->brushtype = index;
+ }
+ /* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_brush_change(wmOperatorType *ot)
+void GPENCIL_OT_sculpt_select(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Change Brush";
- ot->idname = "GPENCIL_OT_brush_change";
- ot->description = "Change active Grease Pencil drawing brush";
+ ot->name = "Select Sculpt Brush";
+ ot->idname = "GPENCIL_OT_sculpt_select";
+ ot->description = "Select a Grease Pencil sculpt brush";
/* callbacks */
- ot->invoke = gp_brush_change_invoke;
- ot->exec = gp_brush_change_exec;
- ot->poll = gp_active_brush_poll;
+ ot->exec = gp_sculpt_select_exec;
+ ot->poll = gp_add_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* gp brush to use (dynamic enum) */
- ot->prop = RNA_def_enum(ot->srna, "brush", DummyRNA_DEFAULT_items, 0, "Grease Pencil Brush", "");
- RNA_def_enum_funcs(ot->prop, ED_gpencil_brushes_enum_itemf);
+ /* properties */
+ RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of Sculpt Brush", 0, INT_MAX);
}
-/* ******************* Move Brush Up/Down ************************** */
+/*********************** Vertex Groups ***********************************/
-enum {
- GP_BRUSH_MOVE_UP = -1,
- GP_BRUSH_MOVE_DOWN = 1
-};
+static bool gpencil_vertex_group_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) && ob->defbase.first) {
+ if (ELEM(ob->mode,
+ OB_MODE_GPENCIL_EDIT,
+ OB_MODE_GPENCIL_SCULPT))
+ {
+ return true;
+ }
+ }
+ }
-static int gp_brush_move_exec(bContext *C, wmOperator *op)
+ return false;
+}
+
+static bool gpencil_vertex_group_weight_poll(bContext *C)
{
- ToolSettings *ts = CTX_data_tool_settings(C);
- bGPDbrush *brush = BKE_gpencil_brush_getactive(ts);
+ Object *ob = CTX_data_active_object(C);
- int direction = RNA_enum_get(op->ptr, "type");
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) && ob->defbase.first) {
+ if (ob->mode == OB_MODE_GPENCIL_WEIGHT) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static int gpencil_vertex_group_assign_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Object *ob = CTX_data_active_object(C);
/* sanity checks */
- if (ELEM(NULL, ts, brush)) {
+ if (ELEM(NULL, ts, ob, ob->data))
return OPERATOR_CANCELLED;
- }
- /* up or down? */
- if (direction == GP_BRUSH_MOVE_UP) {
- /* up */
- BLI_remlink(&ts->gp_brushes, brush);
- BLI_insertlinkbefore(&ts->gp_brushes, brush->prev, brush);
- }
- else if (direction == GP_BRUSH_MOVE_DOWN) {
- /* down */
- BLI_remlink(&ts->gp_brushes, brush);
- BLI_insertlinkafter(&ts->gp_brushes, brush->next, brush);
- }
- else {
- BLI_assert(0);
- }
+ ED_gpencil_vgroup_assign(C, ob, ts->vgroup_weight);
/* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ bGPdata *gpd = ob->data;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_brush_move(wmOperatorType *ot)
+void GPENCIL_OT_vertex_group_assign(wmOperatorType *ot)
{
- static const EnumPropertyItem slot_move[] = {
- {GP_BRUSH_MOVE_UP, "UP", 0, "Up", ""},
- {GP_BRUSH_MOVE_DOWN, "DOWN", 0, "Down", ""},
- {0, NULL, 0, NULL, NULL }
- };
-
/* identifiers */
- ot->name = "Move Brush";
- ot->idname = "GPENCIL_OT_brush_move";
- ot->description = "Move the active Grease Pencil drawing brush up/down in the list";
+ ot->name = "Assign to Vertex Group";
+ ot->idname = "GPENCIL_OT_vertex_group_assign";
+ ot->description = "Assign the selected vertices to the active vertex group";
/* api callbacks */
- ot->exec = gp_brush_move_exec;
- ot->poll = gp_active_brush_poll;
+ ot->poll = gpencil_vertex_group_poll;
+ ot->exec = gpencil_vertex_group_assign_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- ot->prop = RNA_def_enum(ot->srna, "type", slot_move, GP_BRUSH_MOVE_UP, "Type", "");
}
-/* ******************* Brush create presets ************************** */
-
-static int gp_brush_presets_create_exec(bContext *C, wmOperator *UNUSED(op))
+/* remove point from vertex group */
+static int gpencil_vertex_group_remove_from_exec(bContext *C, wmOperator *UNUSED(op))
{
- ToolSettings *ts = CTX_data_tool_settings(C);
- BKE_gpencil_brush_init_presets(ts);
+ Object *ob = CTX_data_active_object(C);
+
+ /* sanity checks */
+ if (ELEM(NULL, ob, ob->data))
+ return OPERATOR_CANCELLED;
+
+ ED_gpencil_vgroup_remove(C, ob);
/* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ bGPdata *gpd = ob->data;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_brush_presets_create(wmOperatorType *ot)
+void GPENCIL_OT_vertex_group_remove_from(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Create Preset Brushes";
- ot->idname = "GPENCIL_OT_brush_presets_create";
- ot->description = "Create a set of predefined Grease Pencil drawing brushes";
+ ot->name = "Remove from Vertex Group";
+ ot->idname = "GPENCIL_OT_vertex_group_remove_from";
+ ot->description = "Remove the selected vertices from active or all vertex group(s)";
/* api callbacks */
- ot->exec = gp_brush_presets_create_exec;
+ ot->poll = gpencil_vertex_group_poll;
+ ot->exec = gpencil_vertex_group_remove_from_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ***************** Copy Brush ************************ */
-
-static int gp_brush_copy_exec(bContext *C, wmOperator *op)
+static int gpencil_vertex_group_select_exec(bContext *C, wmOperator *UNUSED(op))
{
- ToolSettings *ts = CTX_data_tool_settings(C);
-
- /* if there's no existing container */
- if (ts == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Nowhere for brush data to go");
- return OPERATOR_CANCELLED;
- }
-
- bGPDbrush *brush = BKE_gpencil_brush_getactive(ts);
- bGPDbrush *newbrush;
+ Object *ob = CTX_data_active_object(C);
/* sanity checks */
- if (ELEM(NULL, brush))
+ if (ELEM(NULL, ob, ob->data))
return OPERATOR_CANCELLED;
- /* create a brush and duplicate data */
- newbrush = BKE_gpencil_brush_addnew(ts, brush->info, true);
- newbrush->thickness = brush->thickness;
- newbrush->draw_smoothfac = brush->draw_smoothfac;
- newbrush->draw_smoothlvl = brush->draw_smoothlvl;
- newbrush->sublevel = brush->sublevel;
- newbrush->flag = brush->flag;
- newbrush->draw_sensitivity = brush->draw_sensitivity;
- newbrush->draw_strength = brush->draw_strength;
- newbrush->draw_jitter = brush->draw_jitter;
- newbrush->draw_angle = brush->draw_angle;
- newbrush->draw_angle_factor = brush->draw_angle_factor;
- newbrush->draw_random_press = brush->draw_random_press;
- newbrush->draw_random_sub = brush->draw_random_sub;
-
- /* free automatic curves created by default (replaced by copy) */
- curvemapping_free(newbrush->cur_sensitivity);
- curvemapping_free(newbrush->cur_strength);
- curvemapping_free(newbrush->cur_jitter);
-
- /* make a copy of curves */
- newbrush->cur_sensitivity = curvemapping_copy(brush->cur_sensitivity);
- newbrush->cur_strength = curvemapping_copy(brush->cur_strength);
- newbrush->cur_jitter = curvemapping_copy(brush->cur_jitter);
-
- BKE_gpencil_brush_setactive(ts, newbrush);
+ ED_gpencil_vgroup_select(C, ob);
+
/* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ bGPdata *gpd = ob->data;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_brush_copy(wmOperatorType *ot)
+void GPENCIL_OT_vertex_group_select(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Copy Brush";
- ot->idname = "GPENCIL_OT_brush_copy";
- ot->description = "Copy current Grease Pencil drawing brush";
+ ot->name = "Select Vertex Group";
+ ot->idname = "GPENCIL_OT_vertex_group_select";
+ ot->description = "Select all the vertices assigned to the active vertex group";
- /* callbacks */
- ot->exec = gp_brush_copy_exec;
- ot->poll = gp_active_brush_poll;
+ /* api callbacks */
+ ot->poll = gpencil_vertex_group_poll;
+ ot->exec = gpencil_vertex_group_select_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ***************** Select Brush ************************ */
-
-static int gp_brush_select_exec(bContext *C, wmOperator *op)
+static int gpencil_vertex_group_deselect_exec(bContext *C, wmOperator *UNUSED(op))
{
- ToolSettings *ts = CTX_data_tool_settings(C);
+ Object *ob = CTX_data_active_object(C);
- /* if there's no existing container */
- if (ts == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Nowhere to go");
- return OPERATOR_CANCELLED;
- }
-
- const int index = RNA_int_get(op->ptr, "index");
- bGPDbrush *brush = BLI_findlink(&ts->gp_brushes, index);
/* sanity checks */
- if (ELEM(NULL, brush)) {
+ if (ELEM(NULL, ob, ob->data))
return OPERATOR_CANCELLED;
- }
- BKE_gpencil_brush_setactive(ts, brush);
+ ED_gpencil_vgroup_deselect(C, ob);
/* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ bGPdata *gpd = ob->data;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_brush_select(wmOperatorType *ot)
+void GPENCIL_OT_vertex_group_deselect(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Select Brush";
- ot->idname = "GPENCIL_OT_brush_select";
- ot->description = "Select a Grease Pencil drawing brush";
+ ot->name = "Deselect Vertex Group";
+ ot->idname = "GPENCIL_OT_vertex_group_deselect";
+ ot->description = "Deselect all selected vertices assigned to the active vertex group";
- /* callbacks */
- ot->exec = gp_brush_select_exec;
- ot->poll = gp_active_brush_poll;
+ /* api callbacks */
+ ot->poll = gpencil_vertex_group_poll;
+ ot->exec = gpencil_vertex_group_deselect_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of Drawing Brush", 0, INT_MAX);
}
-/* ************************************************ */
-/* Palette Operators */
-
-/* ******************* Add New Palette ************************ */
-
-/* add new palette - wrapper around API */
-static int gp_palette_add_exec(bContext *C, wmOperator *op)
+/* invert */
+static int gpencil_vertex_group_invert_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
- bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Object *ob = CTX_data_active_object(C);
- /* if there's no existing Grease-Pencil data there, add some */
- if (gpd_ptr == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
+ /* sanity checks */
+ if (ELEM(NULL, ts, ob, ob->data))
+ return OPERATOR_CANCELLED;
+
+ MDeformVert *dvert;
+ const int def_nr = ob->actdef - 1;
+ if (!BLI_findlink(&ob->defbase, def_nr))
return OPERATOR_CANCELLED;
- }
- if (*gpd_ptr == NULL)
- *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil"));
- /* add new palette now */
- BKE_gpencil_palette_addnew(*gpd_ptr, DATA_("GP_Palette"), true);
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ for (int i = 0; i < gps->totpoints; i++) {
+ dvert = &gps->dvert[i];
+ if (dvert->dw == NULL) {
+ BKE_gpencil_vgroup_add_point_weight(dvert, def_nr, 1.0f);
+ }
+ else if (dvert->dw->weight == 1.0f) {
+ BKE_gpencil_vgroup_remove_point_weight(dvert, def_nr);
+ }
+ else {
+ dvert->dw->weight = 1.0f - dvert->dw->weight;
+ }
+ }
+ }
+ CTX_DATA_END;
/* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ bGPdata *gpd = ob->data;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_palette_add(wmOperatorType *ot)
+void GPENCIL_OT_vertex_group_invert(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Add Palette";
- ot->idname = "GPENCIL_OT_palette_add";
- ot->description = "Add new Grease Pencil palette for the active Grease Pencil data-block";
+ ot->name = "Invert Vertex Group";
+ ot->idname = "GPENCIL_OT_vertex_group_invert";
+ ot->description = "Invert weights to the active vertex group";
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* api callbacks */
+ ot->poll = gpencil_vertex_group_weight_poll;
+ ot->exec = gpencil_vertex_group_invert_exec;
- /* callbacks */
- ot->exec = gp_palette_add_exec;
- ot->poll = gp_add_poll;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ******************* Remove Active Palette ************************* */
-
-static int gp_palette_remove_exec(bContext *C, wmOperator *op)
+/* smooth */
+static int gpencil_vertex_group_smooth_exec(bContext *C, wmOperator *op)
{
- bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
+ const float fac = RNA_float_get(op->ptr, "factor");
+ const int repeat = RNA_int_get(op->ptr, "repeat");
+
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Object *ob = CTX_data_active_object(C);
/* sanity checks */
- if (ELEM(NULL, gpd, palette))
+ if (ELEM(NULL, ts, ob, ob->data))
return OPERATOR_CANCELLED;
- if (BLI_listbase_count_at_most(&gpd->palettes, 2) < 2) {
- BKE_report(op->reports, RPT_ERROR, "Grease Pencil needs a palette, unable to delete the last one");
- return OPERATOR_CANCELLED;
- }
+ bGPDspoint *pta, *ptb, *ptc;
+ MDeformVert *dverta, *dvertb;
+ const int def_nr = ob->actdef - 1;
+ if (!BLI_findlink(&ob->defbase, def_nr))
+ return OPERATOR_CANCELLED;
- /* make the palette before this the new active palette
- * - use the one after if this is the first
- * - if this is the only palette, this naturally becomes NULL
- */
- if (palette->prev)
- BKE_gpencil_palette_setactive(gpd, palette->prev);
- else
- BKE_gpencil_palette_setactive(gpd, palette->next);
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ for (int s = 0; s < repeat; s++) {
+ for (int i = 0; i < gps->totpoints; i++) {
+ /* previous point */
+ if (i > 0) {
+ pta = &gps->points[i - 1];
+ dverta = &gps->dvert[i - 1];
+ }
+ else {
+ pta = &gps->points[i];
+ dverta = &gps->dvert[i];
+ }
+ /* current */
+ ptb = &gps->points[i];
+ dvertb = &gps->dvert[i];
+ /* next point */
+ if (i + 1 < gps->totpoints) {
+ ptc = &gps->points[i + 1];
+ }
+ else {
+ ptc = &gps->points[i];
+ }
- /* delete the palette now... */
- BKE_gpencil_palette_delete(gpd, palette);
+ float wa = BKE_gpencil_vgroup_use_index(dverta, def_nr);
+ float wb = BKE_gpencil_vgroup_use_index(dvertb, def_nr);
+ CLAMP_MIN(wa, 0.0f);
+ CLAMP_MIN(wb, 0.0f);
+
+ /* the optimal value is the corresponding to the interpolation of the weight
+ * at the distance of point b
+ */
+ const float opfac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
+ const float optimal = interpf(wa, wb, opfac);
+ /* Based on influence factor, blend between original and optimal */
+ wb = interpf(wb, optimal, fac);
+ BKE_gpencil_vgroup_add_point_weight(dvertb, def_nr, wb);
+ }
+ }
+ }
+ CTX_DATA_END;
/* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ bGPdata *gpd = ob->data;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_palette_remove(wmOperatorType *ot)
+void GPENCIL_OT_vertex_group_smooth(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Remove palette";
- ot->idname = "GPENCIL_OT_palette_remove";
- ot->description = "Remove active Grease Pencil palette";
+ ot->name = "Smooth Vertex Group";
+ ot->idname = "GPENCIL_OT_vertex_group_smooth";
+ ot->description = "Smooth weights to the active vertex group";
+ /* api callbacks */
+ ot->poll = gpencil_vertex_group_weight_poll;
+ ot->exec = gpencil_vertex_group_smooth_exec;
+
+ /* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* callbacks */
- ot->exec = gp_palette_remove_exec;
- ot->poll = gp_active_palette_poll;
+ RNA_def_float(ot->srna, "factor", 0.5f, 0.0f, 1.0, "Factor", "", 0.0f, 1.0f);
+ RNA_def_int(ot->srna, "repeat", 1, 1, 10000, "Iterations", "", 1, 200);
}
-/* ********************** Change Palette ***************************** */
+/****************************** Join ***********************************/
+
+/* userdata for joined_gpencil_fix_animdata_cb() */
+typedef struct tJoinGPencil_AdtFixData {
+ bGPdata *src_gpd;
+ bGPdata *tar_gpd;
-static int gp_palette_change_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(evt))
+ GHash *names_map;
+} 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)
{
- uiPopupMenu *pup;
- uiLayout *layout;
+ tJoinGPencil_AdtFixData *afd = (tJoinGPencil_AdtFixData *)user_data;
+ ID *src_id = &afd->src_gpd->id;
+ ID *dst_id = &afd->tar_gpd->id;
- /* call the menu, which will call this operator again, hence the canceled */
- pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
- layout = UI_popup_menu_layout(pup);
- uiItemsEnumO(layout, "GPENCIL_OT_palette_change", "palette");
- UI_popup_menu_end(C, pup);
+ GHashIterator gh_iter;
- return OPERATOR_INTERFACE;
+ /* Fix paths - If this is the target datablock, it will have some "dirty" paths */
+ if ((id == src_id) && fcu->rna_path && strstr(fcu->rna_path, "layers[")) {
+ GHASH_ITER(gh_iter, afd->names_map) {
+ const char *old_name = BLI_ghashIterator_getKey(&gh_iter);
+ const char *new_name = BLI_ghashIterator_getValue(&gh_iter);
+
+ /* only remap if changed; this still means there will be some waste if there aren't many drivers/keys */
+ if (!STREQ(old_name, new_name) && strstr(fcu->rna_path, old_name)) {
+ fcu->rna_path = BKE_animsys_fix_rna_path_rename(id, fcu->rna_path, "layers",
+ old_name, new_name, 0, 0, false);
+
+ /* we don't want to apply a second remapping on this F-Curve now,
+ * so stop trying to fix names names
+ */
+ break;
+ }
+ }
+ }
+
+ /* Fix driver targets */
+ if (fcu->driver) {
+ /* Fix driver references to invalid ID's */
+ for (DriverVar *dvar = fcu->driver->variables.first; dvar; dvar = dvar->next) {
+ /* only change the used targets, since the others will need fixing manually anyway */
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ /* change the ID's used... */
+ if (dtar->id == src_id) {
+ dtar->id = dst_id;
+
+ /* also check on the subtarget...
+ * XXX: 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[")) {
+ GHASH_ITER(gh_iter, afd->names_map) {
+ const char *old_name = BLI_ghashIterator_getKey(&gh_iter);
+ const char *new_name = BLI_ghashIterator_getValue(&gh_iter);
+
+ /* only remap if changed */
+ if (!STREQ(old_name, new_name)) {
+ if ((dtar->rna_path) && strstr(dtar->rna_path, old_name)) {
+ /* Fix up path */
+ dtar->rna_path = BKE_animsys_fix_rna_path_rename(id, dtar->rna_path, "layers",
+ old_name, new_name, 0, 0, false);
+ break; /* no need to try any more names for layer path */
+ }
+ }
+ }
+ }
+ }
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
+ }
}
-static int gp_palette_change_exec(bContext *C, wmOperator *op)
+/* join objects called from OBJECT_OT_join */
+int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
{
- bGPdata *gpd = CTX_data_gpencil_data(C);
- bGPDpalette *palette = NULL;
- int palette_num = RNA_enum_get(op->ptr, "palette");
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Object *obact = CTX_data_active_object(C);
+ bGPdata *gpd_dst = NULL;
+ bool ok = false;
+
+ /* Ensure we're in right mode and that the active object is correct */
+ if (!obact || obact->type != OB_GPENCIL)
+ return OPERATOR_CANCELLED;
- /* Get palette or create new one */
- if (palette_num == -1) {
- /* Create palette */
- palette = BKE_gpencil_palette_addnew(gpd, DATA_("GP_Palette"), true);
+ bGPdata *gpd = (bGPdata *)obact->data;
+ if ((!gpd) || GPENCIL_ANY_MODE(gpd)) {
+ return OPERATOR_CANCELLED;
}
- else {
- /* Try to get palette */
- palette = BLI_findlink(&gpd->palettes, palette_num);
- if (palette == NULL) {
- BKE_reportf(op->reports, RPT_ERROR, "Cannot change to non-existent palette (index = %d)", palette_num);
- return OPERATOR_CANCELLED;
+ /* Ensure all rotations are applied before */
+ // XXX: Why don't we apply them here instead of warning?
+ CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
+ {
+ if (base->object->type == OB_GPENCIL) {
+ if ((base->object->rot[0] != 0) ||
+ (base->object->rot[1] != 0) ||
+ (base->object->rot[2] != 0))
+ {
+ BKE_report(op->reports, RPT_ERROR, "Apply all rotations before join objects");
+ return OPERATOR_CANCELLED;
+ }
}
}
+ CTX_DATA_END;
- /* Set active palette */
- BKE_gpencil_palette_setactive(gpd, palette);
+ CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
+ {
+ if (base->object == obact) {
+ ok = true;
+ break;
+ }
+ }
+ CTX_DATA_END;
- /* updates */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ /* that way the active object is always selected */
+ if (ok == false) {
+ BKE_report(op->reports, RPT_WARNING, "Active object is not a selected grease pencil");
+ return OPERATOR_CANCELLED;
+ }
- return OPERATOR_FINISHED;
-}
+ gpd_dst = obact->data;
+ Object *ob_dst = obact;
+
+ /* loop and join all data */
+ CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
+ {
+ if ((base->object->type == OB_GPENCIL) && (base->object != obact)) {
+ /* we assume that each datablock is not already used in active object */
+ if (obact->data != base->object->data) {
+ Object *ob_src = base->object;
+ bGPdata *gpd_src = base->object->data;
+
+ /* Apply all GP modifiers before */
+ for (GpencilModifierData *md = base->object->greasepencil_modifiers.first; md; md = md->next) {
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
+ if (mti->bakeModifier) {
+ mti->bakeModifier(bmain, depsgraph, md, base->object);
+ }
+ }
-void GPENCIL_OT_palette_change(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Change Palette";
- ot->idname = "GPENCIL_OT_palette_change";
- ot->description = "Change active Grease Pencil palette";
+ /* copy vertex groups to the base one's */
+ int old_idx = 0;
+ for (bDeformGroup *dg = base->object->defbase.first; dg; dg = dg->next) {
+ bDeformGroup *vgroup = MEM_dupallocN(dg);
+ int idx = BLI_listbase_count(&obact->defbase);
+ defgroup_unique_name(vgroup, obact);
+ BLI_addtail(&obact->defbase, vgroup);
+ /* update vertex groups in strokes in original data */
+ for (bGPDlayer *gpl_src = gpd->layers.first; gpl_src; gpl_src = gpl_src->next) {
+ for (bGPDframe *gpf = gpl_src->frames.first; gpf; gpf = gpf->next) {
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ MDeformVert *dvert;
+ int i;
+ for (i = 0, dvert = gps->dvert; i < gps->totpoints; i++, dvert++) {
+ if ((dvert->dw) && (dvert->dw->def_nr == old_idx)) {
+ dvert->dw->def_nr = idx;
+ }
+ }
+ }
+ }
+ }
+ old_idx++;
+ }
+ if (obact->defbase.first && obact->actdef == 0)
+ obact->actdef = 1;
- /* callbacks */
- ot->invoke = gp_palette_change_invoke;
- ot->exec = gp_palette_change_exec;
- ot->poll = gp_active_palette_poll;
+ /* add missing materials reading source materials and checking in destination object */
+ short *totcol = give_totcolp(ob_src);
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ for (short i = 0; i < *totcol; i++) {
+ Material *tmp_ma = give_current_material(ob_src, i + 1);
+ if (BKE_gpencil_get_material_index(ob_dst, tmp_ma) == 0) {
+ BKE_object_material_slot_add(bmain, ob_dst);
+ assign_material(bmain, ob_dst, tmp_ma, ob_dst->totcol, BKE_MAT_ASSIGN_USERPREF);
+ }
+ }
+
+ /* duplicate bGPDlayers */
+ tJoinGPencil_AdtFixData afd = {0};
+ afd.src_gpd = gpd_src;
+ afd.tar_gpd = gpd_dst;
+ afd.names_map = BLI_ghash_str_new("joined_gp_layers_map");
+
+ float imat[3][3], bmat[3][3];
+ float offset_global[3];
+ float offset_local[3];
+
+ sub_v3_v3v3(offset_global, obact->loc, base->object->obmat[3]);
+ copy_m3_m4(bmat, obact->obmat);
+ invert_m3_m3(imat, bmat);
+ mul_m3_v3(imat, offset_global);
+ mul_v3_m3v3(offset_local, imat, offset_global);
+
+
+ for (bGPDlayer *gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) {
+ bGPDlayer *gpl_new = BKE_gpencil_layer_duplicate(gpl_src);
+ float diff_mat[4][4];
+ float inverse_diff_mat[4][4];
+
+ /* recalculate all stroke points */
+ ED_gpencil_parent_location(depsgraph, base->object, gpd_src, gpl_src, diff_mat);
+ invert_m4_m4(inverse_diff_mat, diff_mat);
+
+ Material *ma_src = NULL;
+ int idx;
+ for (bGPDframe *gpf = gpl_new->frames.first; gpf; gpf = gpf->next) {
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+
+ /* reasign material. Look old material and try to find in dst */
+ ma_src = give_current_material(ob_src, gps->mat_nr + 1);
+ if (ma_src != NULL) {
+ idx = BKE_gpencil_get_material_index(ob_dst, ma_src);
+ if (idx > 0) {
+ gps->mat_nr = idx - 1;
+ }
+ else {
+ gps->mat_nr = 0;
+ }
+ }
+ else {
+ gps->mat_nr = 0;
+ }
+
+ bGPDspoint *pt;
+ int i;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ float mpt[3];
+ mul_v3_m4v3(mpt, inverse_diff_mat, &pt->x);
+ sub_v3_v3(mpt, offset_local);
+ mul_v3_m4v3(&pt->x, diff_mat, mpt);
+ }
+ }
+ }
- /* gp palette to use (dynamic enum) */
- ot->prop = RNA_def_enum(ot->srna, "palette", DummyRNA_DEFAULT_items, 0, "Grease Pencil Palette", "");
- RNA_def_enum_funcs(ot->prop, ED_gpencil_palettes_enum_itemf);
+ /* be sure name is unique in new object */
+ BLI_uniquename(&gpd_dst->layers, gpl_new, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(gpl_new->info));
+ BLI_ghash_insert(afd.names_map, BLI_strdup(gpl_src->info), gpl_new->info);
+
+ /* add to destination datablock */
+ BLI_addtail(&gpd_dst->layers, gpl_new);
+ }
+
+ /* Fix all the animation data */
+ BKE_fcurves_main_cb(bmain, joined_gpencil_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,
+ * so that we don't have to worry about ambiguities re which datablock
+ * a layer came from!
+ */
+ if (base->object->adt) {
+ if (obact->adt == NULL) {
+ /* no animdata, so just use a copy of the whole thing */
+ obact->adt = BKE_animdata_copy(bmain, base->object->adt, false, true);
+ }
+ else {
+ /* merge in data - we'll fix the drivers manually */
+ BKE_animdata_merge_copy(bmain, &obact->id, &base->object->id, ADT_MERGECOPY_KEEP_DST, false);
+ }
+ }
+
+ if (gpd_src->adt) {
+ if (gpd_dst->adt == NULL) {
+ /* no animdata, so just use a copy of the whole thing */
+ gpd_dst->adt = BKE_animdata_copy(bmain, gpd_src->adt, false, true);
+ }
+ else {
+ /* merge in data - we'll fix the drivers manually */
+ BKE_animdata_merge_copy(bmain, &gpd_dst->id, &gpd_src->id, ADT_MERGECOPY_KEEP_DST, false);
+ }
+ }
+ }
+
+ /* Free the old object */
+ ED_object_base_free_and_unlink(bmain, scene, base->object);
+ }
+ }
+ CTX_DATA_END;
+
+ DEG_relations_tag_update(bmain); /* because we removed object(s) */
+
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+
+ return OPERATOR_FINISHED;
}
-/* ******************* Lock and hide any color non used in current layer ************************** */
+/* Color Handle operator */
+static bool gpencil_active_color_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+ if (ob && ob->data && (ob->type == OB_GPENCIL)) {
+ short *totcolp = give_totcolp(ob);
+ return *totcolp > 0;
+ }
+ return false;
+}
-static int gp_palette_lock_layer_exec(bContext *C, wmOperator *UNUSED(op))
+
+/* ******************* Lock and hide any color non used in current layer ************************** */
+static int gpencil_lock_layer_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette;
+ Object *ob = CTX_data_active_object(C);
+ MaterialGPencilStyle *gp_style = NULL;
/* sanity checks */
if (ELEM(NULL, gpd))
return OPERATOR_CANCELLED;
- palette = BKE_gpencil_palette_getactive(gpd);
- if (ELEM(NULL, palette))
+ /* first lock and hide all colors */
+ Material *ma = NULL;
+ short *totcol = give_totcolp(ob);
+ if (totcol == 0)
return OPERATOR_CANCELLED;
- /* first lock and hide all colors */
- for (bGPDpalettecolor *palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
- palcolor->flag |= PC_COLOR_LOCKED;
- palcolor->flag |= PC_COLOR_HIDE;
+ for (short i = 0; i < *totcol; i++) {
+ ma = give_current_material(ob, i + 1);
+ gp_style = ma->gp_style;
+ gp_style->flag |= GP_STYLE_COLOR_LOCKED;
+ gp_style->flag |= GP_STYLE_COLOR_HIDE;
}
/* loop all selected strokes and unlock any color used in active layer */
@@ -1558,140 +2059,49 @@ static int gp_palette_lock_layer_exec(bContext *C, wmOperator *UNUSED(op))
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
+ gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
/* unlock/unhide color if not unlocked before */
- if (gps->palcolor != NULL) {
- gps->palcolor->flag &= ~PC_COLOR_LOCKED;
- gps->palcolor->flag &= ~PC_COLOR_HIDE;
+ if (gp_style != NULL) {
+ gp_style->flag &= ~GP_STYLE_COLOR_LOCKED;
+ gp_style->flag &= ~GP_STYLE_COLOR_HIDE;
}
}
}
}
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_palette_lock_layer(wmOperatorType *ot)
+void GPENCIL_OT_lock_layer(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Disable Unused Layer Colors";
- ot->idname = "GPENCIL_OT_palette_lock_layer";
+ ot->idname = "GPENCIL_OT_lock_layer";
ot->description = "Lock and hide any color not used in any layer";
/* api callbacks */
- ot->exec = gp_palette_lock_layer_exec;
+ ot->exec = gpencil_lock_layer_exec;
ot->poll = gp_active_layer_poll;
}
-/* ************************************************ */
-/* Palette Colors Operators */
-
-/* ******************* Add New Palette ************************ */
-
-/* add new palette - wrapper around API */
-static int gp_palettecolor_add_exec(bContext *C, wmOperator *op)
-{
- Main *bmain = CTX_data_main(C);
- bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
- /* if there's no existing Grease-Pencil data there, add some */
- if (gpd_ptr == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
- return OPERATOR_CANCELLED;
- }
- if (*gpd_ptr == NULL)
- *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil"));
-
- /* verify palette */
- bGPDpalette *palette = BKE_gpencil_palette_getactive(*gpd_ptr);
- if (palette == NULL)
- palette = BKE_gpencil_palette_addnew(*gpd_ptr, DATA_("GP_Palette"), true);
-
- /* add new palette color now */
- BKE_gpencil_palettecolor_addnew(palette, DATA_("Color"), true);
-
- /* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-void GPENCIL_OT_palettecolor_add(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Add Palette Color";
- ot->idname = "GPENCIL_OT_palettecolor_add";
- ot->description = "Add new Grease Pencil palette color for the active Grease Pencil data-block";
-
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* callbacks */
- ot->exec = gp_palettecolor_add_exec;
- ot->poll = gp_add_poll;
-}
-
-/* ******************* Remove Active Palette color ************************* */
-
-static int gp_palettecolor_remove_exec(bContext *C, wmOperator *UNUSED(op))
-{
- bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- bGPDpalettecolor *color = BKE_gpencil_palettecolor_getactive(palette);
-
- /* sanity checks */
- if (ELEM(NULL, gpd, palette, color))
- return OPERATOR_CANCELLED;
-
- /* make the palette color before this the new active color
- * - use the one after if this is the first
- * - if this is the only color, this naturally becomes NULL
- */
- if (color->prev)
- BKE_gpencil_palettecolor_setactive(palette, color->prev);
- else
- BKE_gpencil_palettecolor_setactive(palette, color->next);
+/* ********************** Isolate gpencil_ color **************************** */
- /* delete the strokes */
- BKE_gpencil_palettecolor_delete_strokes(gpd, color->info);
-
- /* delete the palette color now... */
- BKE_gpencil_palettecolor_delete(palette, color);
-
- /* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-void GPENCIL_OT_palettecolor_remove(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Remove palette color";
- ot->idname = "GPENCIL_OT_palettecolor_remove";
- ot->description = "Remove active Grease Pencil palette color";
-
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* callbacks */
- ot->exec = gp_palettecolor_remove_exec;
- ot->poll = gp_active_palettecolor_poll;
-}
-
-/* ********************** Isolate palette color **************************** */
-
-static int gp_isolate_palettecolor_exec(bContext *C, wmOperator *op)
+static int gpencil_color_isolate_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- bGPDpalettecolor *active_color = BKE_gpencil_palettecolor_getactive(palette);
- bGPDpalettecolor *palcolor;
+ Object *ob = CTX_data_active_object(C);
+ Material *active_ma = give_current_material(ob, ob->actcol);
+ MaterialGPencilStyle *active_color = BKE_material_gpencil_settings_get(ob, ob->actcol);
+ MaterialGPencilStyle *gp_style;
- int flags = PC_COLOR_LOCKED;
+ int flags = GP_STYLE_COLOR_LOCKED;
bool isolate = false;
if (RNA_boolean_get(op->ptr, "affect_visibility"))
- flags |= PC_COLOR_HIDE;
+ flags |= GP_STYLE_COLOR_HIDE;
if (ELEM(NULL, gpd, active_color)) {
BKE_report(op->reports, RPT_ERROR, "No active color to isolate");
@@ -1699,15 +2109,19 @@ static int gp_isolate_palettecolor_exec(bContext *C, wmOperator *op)
}
/* Test whether to isolate or clear all flags */
- for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
+ Material *ma = NULL;
+ short *totcol = give_totcolp(ob);
+ for (short i = 0; i < *totcol; i++) {
+ ma = give_current_material(ob, i + 1);
/* Skip if this is the active one */
- if (palcolor == active_color)
+ if (ma == active_ma)
continue;
/* If the flags aren't set, that means that the color is
- * not alone, so we have some colors to isolate still
- */
- if ((palcolor->flag & flags) == 0) {
+ * not alone, so we have some colors to isolate still
+ */
+ gp_style = ma->gp_style;
+ if ((gp_style->flag & flags) == 0) {
isolate = true;
break;
}
@@ -1716,72 +2130,78 @@ static int gp_isolate_palettecolor_exec(bContext *C, wmOperator *op)
/* Set/Clear flags as appropriate */
if (isolate) {
/* Set flags on all "other" colors */
- for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
- if (palcolor == active_color)
+ for (short i = 0; i < *totcol; i++) {
+ ma = give_current_material(ob, i + 1);
+ gp_style = ma->gp_style;
+ if (gp_style == active_color)
continue;
else
- palcolor->flag |= flags;
+ gp_style->flag |= flags;
}
}
else {
/* Clear flags - Restore everything else */
- for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
- palcolor->flag &= ~flags;
+ for (short i = 0; i < *totcol; i++) {
+ ma = give_current_material(ob, i + 1);
+ gp_style = ma->gp_style;
+ gp_style->flag &= ~flags;
}
}
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_palettecolor_isolate(wmOperatorType *ot)
+void GPENCIL_OT_color_isolate(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Isolate Palette Color";
- ot->idname = "GPENCIL_OT_palettecolor_isolate";
+ ot->name = "Isolate Color";
+ ot->idname = "GPENCIL_OT_color_isolate";
ot->description = "Toggle whether the active color is the only one that is editable and/or visible";
/* callbacks */
- ot->exec = gp_isolate_palettecolor_exec;
- ot->poll = gp_active_palettecolor_poll;
+ ot->exec = gpencil_color_isolate_exec;
+ ot->poll = gpencil_active_color_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
RNA_def_boolean(ot->srna, "affect_visibility", false, "Affect Visibility", "In addition to toggling "
- "the editability, also affect the visibility");
+ "the editability, also affect the visibility");
}
-/* *********************** Hide Palette colors ******************************** */
+/* *********************** Hide colors ******************************** */
-static int gp_palettecolor_hide_exec(bContext *C, wmOperator *op)
+static int gpencil_color_hide_exec(bContext *C, wmOperator *op)
{
- bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette);
+ Object *ob = CTX_data_active_object(C);
+ MaterialGPencilStyle *active_color = BKE_material_gpencil_settings_get(ob, ob->actcol);
bool unselected = RNA_boolean_get(op->ptr, "unselected");
- /* sanity checks */
- if (ELEM(NULL, gpd, palette, palcolor))
+ Material *ma = NULL;
+ short *totcol = give_totcolp(ob);
+ if (totcol == 0)
return OPERATOR_CANCELLED;
if (unselected) {
- bGPDpalettecolor *color;
-
/* hide unselected */
- for (color = palette->colors.first; color; color = color->next) {
- if (color != palcolor) {
- color->flag |= PC_COLOR_HIDE;
+ MaterialGPencilStyle *color = NULL;
+ for (short i = 0; i < *totcol; i++) {
+ ma = give_current_material(ob, i + 1);
+ color = ma->gp_style;
+ if (active_color != color) {
+ color->flag |= GP_STYLE_COLOR_HIDE;
}
}
}
else {
/* hide selected/active */
- palcolor->flag |= PC_COLOR_HIDE;
+ active_color->flag |= GP_STYLE_COLOR_HIDE;
}
/* notifiers */
@@ -1790,18 +2210,18 @@ static int gp_palettecolor_hide_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_palettecolor_hide(wmOperatorType *ot)
+void GPENCIL_OT_color_hide(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Hide Color(s)";
- ot->idname = "GPENCIL_OT_palettecolor_hide";
+ ot->idname = "GPENCIL_OT_color_hide";
ot->description = "Hide selected/unselected Grease Pencil colors";
/* callbacks */
- ot->exec = gp_palettecolor_hide_exec;
- ot->poll = gp_active_palettecolor_poll; /* NOTE: we need an active color to play with */
+ ot->exec = gpencil_color_hide_exec;
+ ot->poll = gpencil_active_color_poll; /* NOTE: we need an active color to play with */
- /* flags */
+ /* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
@@ -1810,25 +2230,22 @@ void GPENCIL_OT_palettecolor_hide(wmOperatorType *ot)
/* ********************** Show All Colors ***************************** */
-/* poll callback for showing colors */
-static bool gp_palettecolor_reveal_poll(bContext *C)
-{
- return ED_gpencil_data_get_active(C) != NULL;
-}
-
-static int gp_palettecolor_reveal_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_color_reveal_exec(bContext *C, wmOperator *UNUSED(op))
{
- bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- bGPDpalettecolor *palcolor;
+ Object *ob = CTX_data_active_object(C);
+ Material *ma = NULL;
+ short *totcol = give_totcolp(ob);
- /* sanity checks */
- if (ELEM(NULL, gpd, palette))
+ if (totcol == 0)
return OPERATOR_CANCELLED;
/* make all colors visible */
- for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
- palcolor->flag &= ~PC_COLOR_HIDE;
+ MaterialGPencilStyle *gp_style = NULL;
+
+ for (short i = 0; i < *totcol; i++) {
+ ma = give_current_material(ob, i + 1);
+ gp_style = ma->gp_style;
+ gp_style->flag &= ~GP_STYLE_COLOR_HIDE;
}
/* notifiers */
@@ -1837,36 +2254,40 @@ static int gp_palettecolor_reveal_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_palettecolor_reveal(wmOperatorType *ot)
+void GPENCIL_OT_color_reveal(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Show All Colors";
- ot->idname = "GPENCIL_OT_palettecolor_reveal";
- ot->description = "Unhide all hidden Grease Pencil palette colors";
+ ot->idname = "GPENCIL_OT_color_reveal";
+ ot->description = "Unhide all hidden Grease Pencil gpencil_ colors";
/* callbacks */
- ot->exec = gp_palettecolor_reveal_exec;
- ot->poll = gp_palettecolor_reveal_poll;
+ ot->exec = gpencil_color_reveal_exec;
+ ot->poll = gpencil_active_color_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ***************** Lock/Unlock All Palette colors ************************ */
+/* ***************** Lock/Unlock All colors ************************ */
-static int gp_palettecolor_lock_all_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_color_lock_all_exec(bContext *C, wmOperator *UNUSED(op))
{
- bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- bGPDpalettecolor *palcolor;
- /* sanity checks */
- if (ELEM(NULL, gpd, palette))
+ Object *ob = CTX_data_active_object(C);
+ Material *ma = NULL;
+ short *totcol = give_totcolp(ob);
+
+ if (totcol == 0)
return OPERATOR_CANCELLED;
/* make all layers non-editable */
- for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
- palcolor->flag |= PC_COLOR_LOCKED;
+ MaterialGPencilStyle *gp_style = NULL;
+
+ for (short i = 0; i < *totcol; i++) {
+ ma = give_current_material(ob, i + 1);
+ gp_style = ma->gp_style;
+ gp_style->flag |= GP_STYLE_COLOR_LOCKED;
}
/* notifiers */
@@ -1875,16 +2296,16 @@ static int gp_palettecolor_lock_all_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_palettecolor_lock_all(wmOperatorType *ot)
+void GPENCIL_OT_color_lock_all(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Lock All Colors";
- ot->idname = "GPENCIL_OT_palettecolor_lock_all";
+ ot->idname = "GPENCIL_OT_color_lock_all";
ot->description = "Lock all Grease Pencil colors to prevent them from being accidentally modified";
/* callbacks */
- ot->exec = gp_palettecolor_lock_all_exec;
- ot->poll = gp_palettecolor_reveal_poll; /* XXX: could use dedicated poll later */
+ ot->exec = gpencil_color_lock_all_exec;
+ ot->poll = gpencil_active_color_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1892,19 +2313,22 @@ void GPENCIL_OT_palettecolor_lock_all(wmOperatorType *ot)
/* -------------------------- */
-static int gp_palettecolor_unlock_all_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_color_unlock_all_exec(bContext *C, wmOperator *UNUSED(op))
{
- bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- bGPDpalettecolor *palcolor;
+ Object *ob = CTX_data_active_object(C);
+ Material *ma = NULL;
+ short *totcol = give_totcolp(ob);
- /* sanity checks */
- if (ELEM(NULL, gpd, palette))
+ if (totcol == 0)
return OPERATOR_CANCELLED;
/* make all layers editable again*/
- for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
- palcolor->flag &= ~PC_COLOR_LOCKED;
+ MaterialGPencilStyle *gp_style = NULL;
+
+ for (short i = 0; i < *totcol; i++) {
+ ma = give_current_material(ob, i + 1);
+ gp_style = ma->gp_style;
+ gp_style->flag &= ~GP_STYLE_COLOR_LOCKED;
}
/* notifiers */
@@ -1913,94 +2337,32 @@ static int gp_palettecolor_unlock_all_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_palettecolor_unlock_all(wmOperatorType *ot)
+void GPENCIL_OT_color_unlock_all(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Unlock All Colors";
- ot->idname = "GPENCIL_OT_palettecolor_unlock_all";
+ ot->idname = "GPENCIL_OT_color_unlock_all";
ot->description = "Unlock all Grease Pencil colors so that they can be edited";
/* callbacks */
- ot->exec = gp_palettecolor_unlock_all_exec;
- ot->poll = gp_palettecolor_reveal_poll; /* XXX: could use dedicated poll later */
+ ot->exec = gpencil_color_unlock_all_exec;
+ ot->poll = gpencil_active_color_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ******************* Move Color Up/Down ************************** */
-enum {
- GP_COLOR_MOVE_UP = -1,
- GP_COLOR_MOVE_DOWN = 1
-};
+/* ***************** Select all strokes using color ************************ */
-static int gp_palettecolor_move_exec(bContext *C, wmOperator *op)
+static int gpencil_color_select_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette);
-
- int direction = RNA_enum_get(op->ptr, "direction");
+ Object *ob = CTX_data_active_object(C);
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, ob->actcol);
/* sanity checks */
- if (ELEM(NULL, gpd, palette, palcolor))
- return OPERATOR_CANCELLED;
-
- /* up or down? */
- if (direction == GP_COLOR_MOVE_UP) {
- /* up */
- BLI_remlink(&palette->colors, palcolor);
- BLI_insertlinkbefore(&palette->colors, palcolor->prev, palcolor);
- }
- else if (direction == GP_COLOR_MOVE_DOWN) {
- /* down */
- BLI_remlink(&palette->colors, palcolor);
- BLI_insertlinkafter(&palette->colors, palcolor->next, palcolor);
- }
- else {
- BLI_assert(0);
- }
-
- /* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-void GPENCIL_OT_palettecolor_move(wmOperatorType *ot)
-{
- static const EnumPropertyItem slot_move[] = {
- {GP_COLOR_MOVE_UP, "UP", 0, "Up", ""},
- {GP_COLOR_MOVE_DOWN, "DOWN", 0, "Down", ""},
- {0, NULL, 0, NULL, NULL}
- };
-
- /* identifiers */
- ot->name = "Move Palette color";
- ot->idname = "GPENCIL_OT_palettecolor_move";
- ot->description = "Move the active Grease Pencil palette color up/down in the list";
-
- /* api callbacks */
- ot->exec = gp_palettecolor_move_exec;
- ot->poll = gp_palettecolor_reveal_poll; /* XXX: could use dedicated poll later */
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- ot->prop = RNA_def_enum(ot->srna, "direction", slot_move, GP_COLOR_MOVE_UP, "Direction", "");
-}
-
-/* ***************** Select all strokes using Palette color ************************ */
-
-static int gp_palettecolor_select_exec(bContext *C, wmOperator *UNUSED(op))
-{
- bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette);
-
- /* sanity checks */
- if (ELEM(NULL, gpd, palette, palcolor))
+ if (ELEM(NULL, gpd, gp_style))
return OPERATOR_CANCELLED;
/* read all strokes and select*/
@@ -2013,11 +2375,11 @@ static int gp_palettecolor_select_exec(bContext *C, wmOperator *UNUSED(op))
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false)
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false)
continue;
/* select */
- if (strcmp(palcolor->info, gps->colorname) == 0) {
+ if (ob->actcol == gps->mat_nr) {
bGPDspoint *pt;
int i;
@@ -2035,56 +2397,16 @@ static int gp_palettecolor_select_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-void GPENCIL_OT_palettecolor_select(wmOperatorType *ot)
+void GPENCIL_OT_color_select(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select Color";
- ot->idname = "GPENCIL_OT_palettecolor_select";
+ ot->idname = "GPENCIL_OT_color_select";
ot->description = "Select all Grease Pencil strokes using current color";
/* callbacks */
- ot->exec = gp_palettecolor_select_exec;
- ot->poll = gp_palettecolor_reveal_poll; /* XXX: could use dedicated poll later */
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-/* ***************** Copy Palette color ************************ */
-
-static int gp_palettecolor_copy_exec(bContext *C, wmOperator *UNUSED(op))
-{
- bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette);
- bGPDpalettecolor *newcolor;
-
- /* sanity checks */
- if (ELEM(NULL, gpd, palette, palcolor))
- return OPERATOR_CANCELLED;
-
- /* create a new color and duplicate data */
- newcolor = BKE_gpencil_palettecolor_addnew(palette, palcolor->info, true);
- copy_v4_v4(newcolor->color, palcolor->color);
- copy_v4_v4(newcolor->fill, palcolor->fill);
- newcolor->flag = palcolor->flag;
-
- /* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-void GPENCIL_OT_palettecolor_copy(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Copy Color";
- ot->idname = "GPENCIL_OT_palettecolor_copy";
- ot->description = "Copy current Grease Pencil palette color";
-
- /* callbacks */
- ot->exec = gp_palettecolor_copy_exec;
- ot->poll = gp_active_palettecolor_poll;
+ ot->exec = gpencil_color_select_exec;
+ ot->poll = gpencil_active_color_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index ec67b2da161..f7c08239647 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -47,6 +47,7 @@
#include "BLT_translation.h"
+#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -54,12 +55,18 @@
#include "DNA_view3d_types.h"
#include "DNA_gpencil_types.h"
+#include "BKE_main.h"
#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_brush.h"
#include "BKE_gpencil.h"
+#include "BKE_paint.h"
#include "BKE_library.h"
-#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_screen.h"
+#include "BKE_workspace.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -80,31 +87,70 @@
#include "ED_space_api.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
#include "gpencil_intern.h"
/* ************************************************ */
/* Stroke Edit Mode Management */
-
static bool gpencil_editmode_toggle_poll(bContext *C)
{
+ /* if using gpencil object, use this gpd */
+ Object *ob = CTX_data_active_object(C);
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ return ob->data != NULL;
+ }
return ED_gpencil_data_get_active(C) != NULL;
}
-static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *op)
{
+ const int back = RNA_boolean_get(op->ptr, "back");
+ Depsgraph *depsgraph = CTX_data_depsgraph(C); \
bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bool is_object = false;
+ short mode;
+ /* if using a gpencil object, use this datablock */
+ Object *ob = CTX_data_active_object(C);
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ gpd = ob->data;
+ is_object = true;
+ }
- if (gpd == NULL)
+ if (gpd == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active GP data");
return OPERATOR_CANCELLED;
+ }
/* Just toggle editmode flag... */
gpd->flag ^= GP_DATA_STROKE_EDITMODE;
/* recalculate parent matrix */
if (gpd->flag & GP_DATA_STROKE_EDITMODE) {
- ED_gpencil_reset_layers_parent(gpd);
+ ED_gpencil_reset_layers_parent(depsgraph, ob, gpd);
+ }
+ /* set mode */
+ if (gpd->flag & GP_DATA_STROKE_EDITMODE) {
+ mode = OB_MODE_GPENCIL_EDIT;
+ }
+ else {
+ mode = OB_MODE_OBJECT;
+ }
+
+ if (is_object) {
+ /* try to back previous mode */
+ if ((ob->restore_mode) && ((gpd->flag & GP_DATA_STROKE_EDITMODE) == 0) && (back == 1)) {
+ mode = ob->restore_mode;
+ }
+ ob->restore_mode = ob->mode;
+ ob->mode = mode;
}
+ /* setup other modes */
+ ED_gpencil_setup_modes(C, gpd, mode);
+ /* set cache as dirty */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
WM_event_add_notifier(C, NC_GPENCIL | ND_GPENCIL_EDITMODE, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);
@@ -114,6 +160,8 @@ static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *UNUSED(op))
void GPENCIL_OT_editmode_toggle(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Strokes Edit Mode Toggle";
ot->idname = "GPENCIL_OT_editmode_toggle";
@@ -125,6 +173,259 @@ void GPENCIL_OT_editmode_toggle(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
+
+ /* properties */
+ prop = RNA_def_boolean(ot->srna, "back", 0, "Return to Previous Mode", "Return to previous mode");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+}
+
+/* Stroke Paint Mode Management */
+
+static bool gpencil_paintmode_toggle_poll(bContext *C)
+{
+ /* if using gpencil object, use this gpd */
+ Object *ob = CTX_data_active_object(C);
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ return ob->data != NULL;
+ }
+ return ED_gpencil_data_get_active(C) != NULL;
+}
+
+static int gpencil_paintmode_toggle_exec(bContext *C, wmOperator *op)
+{
+ const bool back = RNA_boolean_get(op->ptr, "back");
+
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+
+ bool is_object = false;
+ short mode;
+ /* if using a gpencil object, use this datablock */
+ Object *ob = CTX_data_active_object(C);
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ gpd = ob->data;
+ is_object = true;
+ }
+
+ if (gpd == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* Just toggle paintmode flag... */
+ gpd->flag ^= GP_DATA_STROKE_PAINTMODE;
+ /* set mode */
+ if (gpd->flag & GP_DATA_STROKE_PAINTMODE) {
+ mode = OB_MODE_GPENCIL_PAINT;
+ }
+ else {
+ mode = OB_MODE_OBJECT;
+ }
+
+ if (is_object) {
+ /* try to back previous mode */
+ if ((ob->restore_mode) && ((gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0) && (back == 1)) {
+ mode = ob->restore_mode;
+ }
+ ob->restore_mode = ob->mode;
+ ob->mode = mode;
+ }
+
+ /* be sure we have brushes */
+ Paint *paint = BKE_brush_get_gpencil_paint(ts);
+ /* if not exist, create a new one */
+ if (paint->brush == NULL) {
+ BKE_brush_gpencil_presets(C);
+ }
+
+ /* setup other modes */
+ ED_gpencil_setup_modes(C, gpd, mode);
+ /* set cache as dirty */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_paintmode_toggle(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Strokes Paint Mode Toggle";
+ ot->idname = "GPENCIL_OT_paintmode_toggle";
+ ot->description = "Enter/Exit paint mode for Grease Pencil strokes";
+
+ /* callbacks */
+ ot->exec = gpencil_paintmode_toggle_exec;
+ ot->poll = gpencil_paintmode_toggle_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
+
+ /* properties */
+ prop = RNA_def_boolean(ot->srna, "back", 0, "Return to Previous Mode", "Return to previous mode");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+}
+
+/* Stroke Sculpt Mode Management */
+
+static bool gpencil_sculptmode_toggle_poll(bContext *C)
+{
+ /* if using gpencil object, use this gpd */
+ Object *ob = CTX_data_active_object(C);
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ return ob->data != NULL;
+ }
+ return ED_gpencil_data_get_active(C) != NULL;
+}
+
+static int gpencil_sculptmode_toggle_exec(bContext *C, wmOperator *op)
+{
+ const bool back = RNA_boolean_get(op->ptr, "back");
+
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bool is_object = false;
+ short mode;
+ /* if using a gpencil object, use this datablock */
+ Object *ob = CTX_data_active_object(C);
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ gpd = ob->data;
+ is_object = true;
+ }
+
+ if (gpd == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* Just toggle sculptmode flag... */
+ gpd->flag ^= GP_DATA_STROKE_SCULPTMODE;
+ /* set mode */
+ if (gpd->flag & GP_DATA_STROKE_SCULPTMODE) {
+ mode = OB_MODE_GPENCIL_SCULPT;
+ }
+ else {
+ mode = OB_MODE_OBJECT;
+ }
+
+ if (is_object) {
+ /* try to back previous mode */
+ if ((ob->restore_mode) && ((gpd->flag & GP_DATA_STROKE_SCULPTMODE) == 0) && (back == 1)) {
+ mode = ob->restore_mode;
+ }
+ ob->restore_mode = ob->mode;
+ ob->mode = mode;
+ }
+
+ /* setup other modes */
+ ED_gpencil_setup_modes(C, gpd, mode);
+ /* set cache as dirty */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_sculptmode_toggle(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Strokes Sculpt Mode Toggle";
+ ot->idname = "GPENCIL_OT_sculptmode_toggle";
+ ot->description = "Enter/Exit sculpt mode for Grease Pencil strokes";
+
+ /* callbacks */
+ ot->exec = gpencil_sculptmode_toggle_exec;
+ ot->poll = gpencil_sculptmode_toggle_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
+
+ /* properties */
+ prop = RNA_def_boolean(ot->srna, "back", 0, "Return to Previous Mode", "Return to previous mode");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+}
+
+/* Stroke Weight Paint Mode Management */
+
+static bool gpencil_weightmode_toggle_poll(bContext *C)
+{
+ /* if using gpencil object, use this gpd */
+ Object *ob = CTX_data_active_object(C);
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ return ob->data != NULL;
+ }
+ return ED_gpencil_data_get_active(C) != NULL;
+}
+
+static int gpencil_weightmode_toggle_exec(bContext *C, wmOperator *op)
+{
+ const bool back = RNA_boolean_get(op->ptr, "back");
+
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bool is_object = false;
+ short mode;
+ /* if using a gpencil object, use this datablock */
+ Object *ob = CTX_data_active_object(C);
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ gpd = ob->data;
+ is_object = true;
+ }
+
+ if (gpd == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* Just toggle weightmode flag... */
+ gpd->flag ^= GP_DATA_STROKE_WEIGHTMODE;
+ /* set mode */
+ if (gpd->flag & GP_DATA_STROKE_WEIGHTMODE) {
+ mode = OB_MODE_GPENCIL_WEIGHT;
+ }
+ else {
+ mode = OB_MODE_OBJECT;
+ }
+
+ if (is_object) {
+ /* try to back previous mode */
+ if ((ob->restore_mode) && ((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && (back == 1)) {
+ mode = ob->restore_mode;
+ }
+ ob->restore_mode = ob->mode;
+ ob->mode = mode;
+ }
+
+ /* setup other modes */
+ ED_gpencil_setup_modes(C, gpd, mode);
+ /* set cache as dirty */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_weightmode_toggle(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Strokes Weight Mode Toggle";
+ ot->idname = "GPENCIL_OT_weightmode_toggle";
+ ot->description = "Enter/Exit weight paint mode for Grease Pencil strokes";
+
+ /* callbacks */
+ ot->exec = gpencil_weightmode_toggle_exec;
+ ot->poll = gpencil_weightmode_toggle_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
+
+ /* properties */
+ prop = RNA_def_boolean(ot->srna, "back", 0, "Return to Previous Mode", "Return to previous mode");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
/* ************************************************ */
@@ -137,21 +438,30 @@ static bool gp_stroke_edit_poll(bContext *C)
return CTX_DATA_COUNT(C, editable_gpencil_strokes) != 0;
}
+/* poll callback to verify edit mode in 3D view only */
+static bool gp_strokes_edit3d_poll(bContext *C)
+{
+ /* 2 Requirements:
+ * - 1) Editable GP data
+ * - 2) 3D View only
+ */
+ return (gp_stroke_edit_poll(C) && ED_operator_view3d_active(C));
+}
+
/* ************ Stroke Hide selection Toggle ************** */
static int gpencil_hideselect_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
- ToolSettings *ts = CTX_data_tool_settings(C);
-
- if (ts == NULL)
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d == NULL)
return OPERATOR_CANCELLED;
/* Just toggle alpha... */
- if (ts->gp_sculpt.alpha > 0.0f) {
- ts->gp_sculpt.alpha = 0.0f;
+ if (v3d->vertex_opacity > 0.0f) {
+ v3d->vertex_opacity = 0.0f;
}
else {
- ts->gp_sculpt.alpha = 1.0f;
+ v3d->vertex_opacity = 1.0f;
}
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
@@ -220,7 +530,7 @@ static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes, co
/* make a stupid copy first of the entire stroke (to get the flags too) */
gpsd = MEM_dupallocN(gps);
- BLI_strncpy(gpsd->tmp_layerinfo, layername, sizeof(gpsd->tmp_layerinfo)); /* saves original layer name */
+ BLI_strncpy(gpsd->runtime.tmp_layerinfo, layername, sizeof(gpsd->runtime.tmp_layerinfo)); /* saves original layer name */
/* initialize triangle memory - will be calculated on next redraw */
gpsd->triangles = NULL;
@@ -232,6 +542,20 @@ static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes, co
memcpy(gpsd->points, gps->points + start_idx, sizeof(bGPDspoint) * len);
gpsd->totpoints = len;
+ if (gps->dvert != NULL) {
+ gpsd->dvert = MEM_callocN(sizeof(MDeformVert) * len, "gps stroke weights copy");
+ memcpy(gpsd->dvert, gps->dvert + start_idx, sizeof(MDeformVert) * len);
+
+ /* Copy weights */
+ int e = start_idx;
+ for (int j = 0; j < gpsd->totpoints; j++) {
+ MDeformVert *dvert_dst = &gps->dvert[e];
+ MDeformVert *dvert_src = &gps->dvert[j];
+ dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
+ e++;
+ }
+ }
+
/* add to temp buffer */
gpsd->next = gpsd->prev = NULL;
BLI_addtail(new_strokes, gpsd);
@@ -252,6 +576,11 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) {
+ BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition");
+ return OPERATOR_CANCELLED;
+ }
+
/* for each visible (and editable) layer's selected strokes,
* copy the strokes into a temporary buffer, then append
* once all done
@@ -279,8 +608,12 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
/* make direct copies of the stroke and its points */
gpsd = MEM_dupallocN(gps);
- BLI_strncpy(gpsd->tmp_layerinfo, gpl->info, sizeof(gpsd->tmp_layerinfo));
+ BLI_strncpy(gpsd->runtime.tmp_layerinfo, gpl->info, sizeof(gpsd->runtime.tmp_layerinfo));
gpsd->points = MEM_dupallocN(gps->points);
+ if (gps->dvert != NULL) {
+ gpsd->dvert = MEM_dupallocN(gps->dvert);
+ BKE_gpencil_stroke_weights_duplicate(gps, gpsd);
+ }
/* triangle information - will be calculated on next redraw */
gpsd->flag |= GP_STROKE_RECALC_CACHES;
@@ -309,6 +642,7 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -342,7 +676,7 @@ void GPENCIL_OT_duplicate(wmOperatorType *ot)
/* NOTE: is exposed within the editors/gpencil module so that other tools can use it too */
ListBase gp_strokes_copypastebuf = {NULL, NULL};
-/* Hash for hanging on to all the palette colors used by strokes in the buffer
+/* 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 datablocks,
* or after a color used by a stroke in the buffer gets deleted (via user action or undo).
@@ -354,11 +688,11 @@ void ED_gpencil_strokes_copybuf_free(void)
{
bGPDstroke *gps, *gpsn;
- /* Free the palettes buffer
- * NOTE: This is done before the strokes so that the name ptrs (keys) are still safe
+ /* 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);
+ BLI_ghash_free(gp_strokes_copypastebuf_colors, NULL, NULL);
gp_strokes_copypastebuf_colors = NULL;
}
@@ -366,8 +700,15 @@ void ED_gpencil_strokes_copybuf_free(void)
for (gps = gp_strokes_copypastebuf.first; gps; gps = gpsn) {
gpsn = gps->next;
- if (gps->points) MEM_freeN(gps->points);
- if (gps->triangles) MEM_freeN(gps->triangles);
+ if (gps->points) {
+ MEM_freeN(gps->points);
+ }
+ if (gps->dvert) {
+ BKE_gpencil_free_stroke_weights(gps);
+ MEM_freeN(gps->dvert);
+ }
+
+ MEM_SAFE_FREE(gps->triangles);
BLI_freelinkN(&gp_strokes_copypastebuf, gps);
}
@@ -378,38 +719,26 @@ void ED_gpencil_strokes_copybuf_free(void)
/* Ensure that destination datablock has all the colours the pasted strokes need
* Helper function for copy-pasting strokes
*/
-GHash *gp_copybuf_validate_colormap(bGPdata *gpd)
+GHash *gp_copybuf_validate_colormap(bContext *C)
{
+ Main *bmain = CTX_data_main(C);
+ Object *ob = CTX_data_active_object(C);
GHash *new_colors = BLI_ghash_str_new("GPencil Paste Dst Colors");
GHashIterator gh_iter;
- /* If there's no active palette yet (i.e. new datablock), add one */
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- if (palette == NULL) {
- palette = BKE_gpencil_palette_addnew(gpd, "Pasted Palette", true);
- }
-
- /* For each color, figure out what to map to... */
+ /* For each color, check if exist and add if not */
GHASH_ITER(gh_iter, gp_strokes_copypastebuf_colors) {
- bGPDpalettecolor *palcolor;
- char *name = BLI_ghashIterator_getKey(&gh_iter);
-
- /* Look for existing color to map to */
- /* XXX: What to do if same name but different color? Behaviour here should depend on a property? */
- palcolor = BKE_gpencil_palettecolor_getbyname(palette, name);
- if (palcolor == NULL) {
- /* Doesn't Exist - Create new matching color for this palette */
- /* XXX: This still doesn't fix the pasting across file boundaries problem... */
- bGPDpalettecolor *src_color = BLI_ghashIterator_getValue(&gh_iter);
- palcolor = MEM_dupallocN(src_color);
- BLI_addtail(&palette->colors, palcolor);
+ int *key = BLI_ghashIterator_getKey(&gh_iter);
+ Material *ma = BLI_ghashIterator_getValue(&gh_iter);
- BLI_uniquename(&palette->colors, palcolor, DATA_("GP Color"), '.', offsetof(bGPDpalettecolor, info), sizeof(palcolor->info));
+ if (BKE_gpencil_get_material_index(ob, ma) == 0) {
+ BKE_object_material_slot_add(bmain, ob);
+ assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
}
/* Store this mapping (for use later when pasting) */
- BLI_ghash_insert(new_colors, name, palcolor);
+ BLI_ghash_insert(new_colors, key, ma);
}
return new_colors;
@@ -420,6 +749,7 @@ GHash *gp_copybuf_validate_colormap(bGPdata *gpd)
static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
{
+ Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
if (gpd == NULL) {
@@ -427,6 +757,11 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) {
+ BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition");
+ return OPERATOR_CANCELLED;
+ }
+
/* clear the buffer first */
ED_gpencil_strokes_copybuf_free();
@@ -455,8 +790,12 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
/* make direct copies of the stroke and its points */
gpsd = MEM_dupallocN(gps);
- BLI_strncpy(gpsd->tmp_layerinfo, gpl->info, sizeof(gpsd->tmp_layerinfo)); /* saves original layer name */
+ BLI_strncpy(gpsd->runtime.tmp_layerinfo, gpl->info, sizeof(gpsd->runtime.tmp_layerinfo)); /* saves original layer name */
gpsd->points = MEM_dupallocN(gps->points);
+ if (gps->dvert != NULL) {
+ gpsd->dvert = MEM_dupallocN(gps->dvert);
+ BKE_gpencil_stroke_weights_duplicate(gps, gpsd);
+ }
/* triangles cache - will be recalculated on next redraw */
gpsd->flag |= GP_STROKE_RECALC_CACHES;
@@ -476,17 +815,15 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- /* Build up hash of colors used in these strokes, making copies of these to protect against dangling pointers */
+ /* Build up hash of material colors used in these strokes */
if (gp_strokes_copypastebuf.first) {
gp_strokes_copypastebuf_colors = BLI_ghash_str_new("GPencil CopyBuf Colors");
-
+ Material *ma = NULL;
for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
- if (BLI_ghash_haskey(gp_strokes_copypastebuf_colors, gps->colorname) == false) {
- bGPDpalettecolor *color = MEM_dupallocN(gps->palcolor);
-
- BLI_ghash_insert(gp_strokes_copypastebuf_colors, gps->colorname, color);
- gps->palcolor = color;
+ ma = give_current_material(ob, gps->mat_nr + 1);
+ if (BLI_ghash_haskey(gp_strokes_copypastebuf_colors, &gps->mat_nr) == false) {
+ BLI_ghash_insert(gp_strokes_copypastebuf_colors, &gps->mat_nr, ma);
}
}
}
@@ -534,9 +871,11 @@ typedef enum eGP_PasteMode {
static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); /* only use active for copy merge */
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
bGPDframe *gpf;
eGP_PasteMode type = RNA_enum_get(op->ptr, "type");
@@ -547,6 +886,10 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
return OPERATOR_CANCELLED;
}
+ else if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) {
+ BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition");
+ return OPERATOR_CANCELLED;
+ }
else if (BLI_listbase_is_empty(&gp_strokes_copypastebuf)) {
BKE_report(op->reports, RPT_ERROR, "No strokes to paste, select and copy some points before trying again");
return OPERATOR_CANCELLED;
@@ -599,14 +942,14 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* Ensure that all the necessary colors exist */
- new_colors = gp_copybuf_validate_colormap(gpd);
+ new_colors = gp_copybuf_validate_colormap(C);
/* Copy over the strokes from the buffer (and adjust the colors) */
for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
/* Need to verify if layer exists */
if (type != GP_COPY_MERGE) {
- gpl = BLI_findstring(&gpd->layers, gps->tmp_layerinfo, offsetof(bGPDlayer, info));
+ gpl = BLI_findstring(&gpd->layers, gps->runtime.tmp_layerinfo, offsetof(bGPDlayer, info));
if (gpl == NULL) {
/* no layer - use active (only if layer deleted before paste) */
gpl = CTX_data_active_gpencil_layer(C);
@@ -618,28 +961,33 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
* we are obliged to add a new frame if one
* doesn't exist already
*/
- gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true);
+ gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, true);
if (gpf) {
/* Create new stroke */
bGPDstroke *new_stroke = MEM_dupallocN(gps);
- new_stroke->tmp_layerinfo[0] = '\0';
+ new_stroke->runtime.tmp_layerinfo[0] = '\0';
new_stroke->points = MEM_dupallocN(gps->points);
-
+ if (gps->dvert != NULL) {
+ new_stroke->dvert = MEM_dupallocN(gps->dvert);
+ BKE_gpencil_stroke_weights_duplicate(gps, new_stroke);
+ }
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
new_stroke->triangles = NULL;
new_stroke->next = new_stroke->prev = NULL;
BLI_addtail(&gpf->strokes, new_stroke);
- /* Fix color references */
- BLI_assert(new_stroke->colorname[0] != '\0');
- new_stroke->palcolor = BLI_ghash_lookup(new_colors, new_stroke->colorname);
-
- BLI_assert(new_stroke->palcolor != NULL);
- BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname));
+ /* Remap material */
+ Material *ma = BLI_ghash_lookup(new_colors, &new_stroke->mat_nr);
+ if ((ma) && (BKE_gpencil_get_material_index(ob, ma) > 0)) {
+ gps->mat_nr = BKE_gpencil_get_material_index(ob, ma) - 1;
+ CLAMP_MIN(gps->mat_nr, 0);
+ }
+ else {
+ gps->mat_nr = 0; /* only if the color is not found */
+ }
- /*new_stroke->flag |= GP_STROKE_RECALC_COLOR; */
}
}
}
@@ -648,6 +996,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
BLI_ghash_free(new_colors, NULL, NULL);
/* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -697,10 +1046,17 @@ static int gp_move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *U
static int gp_move_to_layer_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
bGPDlayer *target_layer = NULL;
ListBase strokes = {NULL, NULL};
int layer_num = RNA_enum_get(op->ptr, "layer");
+ if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) {
+ BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition");
+ return OPERATOR_CANCELLED;
+ }
+
/* Get layer or create new one */
if (layer_num == -1) {
/* Create layer */
@@ -748,14 +1104,14 @@ static int gp_move_to_layer_exec(bContext *C, wmOperator *op)
/* Paste them all in one go */
if (strokes.first) {
- Scene *scene = CTX_data_scene(C);
- bGPDframe *gpf = BKE_gpencil_layer_getframe(target_layer, CFRA, true);
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(target_layer, cfra_eval, true);
BLI_movelisttolist(&gpf->strokes, &strokes);
BLI_assert((strokes.first == strokes.last) && (strokes.first == NULL));
}
/* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -804,8 +1160,10 @@ static bool UNUSED_FUNCTION(gp_blank_frame_add_poll)(bContext *C)
static int gp_blank_frame_add_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
bGPDlayer *active_gpl = BKE_gpencil_layer_getactive(gpd);
const bool all_layers = RNA_boolean_get(op->ptr, "all_layers");
@@ -826,7 +1184,7 @@ static int gp_blank_frame_add_exec(bContext *C, wmOperator *op)
}
/* 1) Check for an existing frame on the current frame */
- bGPDframe *gpf = BKE_gpencil_layer_find_frame(gpl, CFRA);
+ bGPDframe *gpf = BKE_gpencil_layer_find_frame(gpl, cfra_eval);
if (gpf) {
/* Shunt all frames after (and including) the existing one later by 1-frame */
for (; gpf; gpf = gpf->next) {
@@ -835,11 +1193,12 @@ static int gp_blank_frame_add_exec(bContext *C, wmOperator *op)
}
/* 2) Now add a new frame, with nothing in it */
- gpl->actframe = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_NEW);
+ gpl->actframe = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_ADD_NEW);
}
CTX_DATA_END;
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -876,10 +1235,13 @@ static bool gp_actframe_delete_poll(bContext *C)
/* delete active frame - wrapper around API calls */
static int gp_actframe_delete_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0);
+
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0);
/* if there's no existing Grease-Pencil data there, add some */
if (gpd == NULL) {
@@ -895,6 +1257,7 @@ static int gp_actframe_delete_exec(bContext *C, wmOperator *op)
BKE_gpencil_layer_delframe(gpl, gpf);
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -928,13 +1291,16 @@ static bool gp_actframe_delete_all_poll(bContext *C)
static int gp_actframe_delete_all_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
bool success = false;
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
/* try to get the "active" frame - but only if it actually occurs on this frame */
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0);
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0);
if (gpf == NULL)
continue;
@@ -949,6 +1315,7 @@ static int gp_actframe_delete_all_exec(bContext *C, wmOperator *op)
/* updates */
if (success) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
@@ -983,43 +1350,69 @@ typedef enum eGP_DeleteMode {
GP_DELETEOP_FRAME = 2,
} eGP_DeleteMode;
+typedef enum eGP_DissolveMode {
+ /* dissolve all selected points */
+ GP_DISSOLVE_POINTS = 0,
+ /* dissolve between selected points */
+ GP_DISSOLVE_BETWEEN = 1,
+ /* dissolve unselected points */
+ GP_DISSOLVE_UNSELECT = 2,
+} eGP_DissolveMode;
+
/* ----------------------------------- */
/* Delete selected strokes */
static int gp_delete_selected_strokes(bContext *C)
{
bool changed = false;
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
- bGPDframe *gpf = gpl->actframe;
- bGPDstroke *gps, *gpsn;
+ bGPDframe *init_gpf = gpl->actframe;
+ if (is_multiedit) {
+ init_gpf = gpl->frames.first;
+ }
- if (gpf == NULL)
- continue;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ bGPDstroke *gps, *gpsn;
- /* simply delete strokes which are selected */
- for (gps = gpf->strokes.first; gps; gps = gpsn) {
- gpsn = gps->next;
+ if (gpf == NULL)
+ continue;
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false)
- continue;
+ /* simply delete strokes which are selected */
+ for (gps = gpf->strokes.first; gps; gps = gpsn) {
+ gpsn = gps->next;
- /* free stroke if selected */
- if (gps->flag & GP_STROKE_SELECT) {
- /* free stroke memory arrays, then stroke itself */
- if (gps->points) MEM_freeN(gps->points);
- if (gps->triangles) MEM_freeN(gps->triangles);
- BLI_freelinkN(&gpf->strokes, gps);
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
- changed = true;
+ /* free stroke if selected */
+ if (gps->flag & GP_STROKE_SELECT) {
+ /* free stroke memory arrays, then stroke itself */
+ if (gps->points) {
+ MEM_freeN(gps->points);
+ }
+ if (gps->dvert) {
+ BKE_gpencil_free_stroke_weights(gps);
+ MEM_freeN(gps->dvert);
+ }
+ MEM_SAFE_FREE(gps->triangles);
+ BLI_freelinkN(&gpf->strokes, gps);
+
+ changed = true;
+ }
+ }
}
}
}
CTX_DATA_END;
if (changed) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
@@ -1031,88 +1424,238 @@ static int gp_delete_selected_strokes(bContext *C)
/* ----------------------------------- */
/* Delete selected points but keep the stroke */
-static int gp_dissolve_selected_points(bContext *C)
+static int gp_dissolve_selected_points(bContext *C, eGP_DissolveMode mode)
{
+ Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
bool changed = false;
+ int first = 0;
+ int last = 0;
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
- bGPDframe *gpf = gpl->actframe;
- bGPDstroke *gps, *gpsn;
+ bGPDframe *init_gpf = gpl->actframe;
+ if (is_multiedit) {
+ init_gpf = gpl->frames.first;
+ }
- if (gpf == NULL)
- continue;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
- /* simply delete points from selected strokes
- * NOTE: we may still have to remove the stroke if it ends up having no points!
- */
- for (gps = gpf->strokes.first; gps; gps = gpsn) {
- gpsn = gps->next;
+ bGPDstroke *gps, *gpsn;
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false)
- continue;
- /* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false)
- continue;
+ if (gpf == NULL)
+ continue;
- if (gps->flag & GP_STROKE_SELECT) {
- bGPDspoint *pt;
- int i;
+ /* simply delete points from selected strokes
+ * NOTE: we may still have to remove the stroke if it ends up having no points!
+ */
+ for (gps = gpf->strokes.first; gps; gps = gpsn) {
+ gpsn = gps->next;
+
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false)
+ continue;
+
+ /* the stroke must have at least one point selected for any operator */
+ if (gps->flag & GP_STROKE_SELECT) {
+ bGPDspoint *pt;
+ MDeformVert *dvert = NULL;
+ int i;
+
+ int tot = gps->totpoints; /* number of points in new buffer */
+
+ /* first pass: count points to remove */
+ switch (mode) {
+ case GP_DISSOLVE_POINTS:
+ /* Count how many points are selected (i.e. how many to remove) */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ /* selected point - one of the points to remove */
+ tot--;
+ }
+ }
+ break;
+ case GP_DISSOLVE_BETWEEN:
+ /* need to find first and last point selected */
+ first = -1;
+ last = 0;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ if (first < 0) {
+ first = i;
+ }
+ last = i;
+ }
+ }
+ /* count unselected points in the range */
+ for (i = first, pt = gps->points + first; i < last; i++, pt++) {
+ if ((pt->flag & GP_SPOINT_SELECT) == 0) {
+ tot--;
+ }
+ }
+ break;
+ case GP_DISSOLVE_UNSELECT:
+ /* count number of unselected points */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if ((pt->flag & GP_SPOINT_SELECT) == 0) {
+ tot--;
+ }
+ }
+ break;
+ default:
+ return false;
+ break;
+ }
- int tot = gps->totpoints; /* number of points in new buffer */
+ /* if no points are left, we simply delete the entire stroke */
+ if (tot <= 0) {
+ /* remove the entire stroke */
+ if (gps->points) {
+ MEM_freeN(gps->points);
+ }
+ if (gps->dvert) {
+ BKE_gpencil_free_stroke_weights(gps);
+ MEM_freeN(gps->dvert);
+ }
+ if (gps->triangles) {
+ MEM_freeN(gps->triangles);
+ }
+ BLI_freelinkN(&gpf->strokes, gps);
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ }
+ else {
+ /* just copy all points to keep into a smaller buffer */
+ bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * tot, "new gp stroke points copy");
+ bGPDspoint *npt = new_points;
- /* First Pass: Count how many points are selected (i.e. how many to remove) */
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if (pt->flag & GP_SPOINT_SELECT) {
- /* selected point - one of the points to remove */
- tot--;
- }
- }
+ MDeformVert *new_dvert = NULL;
+ MDeformVert *ndvert = NULL;
- /* if no points are left, we simply delete the entire stroke */
- if (tot <= 0) {
- /* remove the entire stroke */
- MEM_freeN(gps->points);
- if (gps->triangles) {
- MEM_freeN(gps->triangles);
- }
- BLI_freelinkN(&gpf->strokes, gps);
- }
- else {
- /* just copy all unselected into a smaller buffer */
- bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * tot, "new gp stroke points copy");
- bGPDspoint *npt = new_points;
+ if (gps->dvert != NULL) {
+ new_dvert = MEM_callocN(sizeof(MDeformVert) * tot, "new gp stroke weights copy");
+ ndvert = new_dvert;
+ }
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if ((pt->flag & GP_SPOINT_SELECT) == 0) {
- *npt = *pt;
- npt++;
- }
- }
+ switch (mode) {
+ case GP_DISSOLVE_POINTS:
+ (gps->dvert != NULL) ? dvert = gps->dvert : NULL;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if ((pt->flag & GP_SPOINT_SELECT) == 0) {
+ *npt = *pt;
+ npt++;
+
+ if (gps->dvert != NULL) {
+ *ndvert = *dvert;
+ ndvert->dw = MEM_dupallocN(dvert->dw);
+ ndvert++;
+ dvert++;
+ }
+ }
+ }
+ break;
+ case GP_DISSOLVE_BETWEEN:
+ /* copy first segment */
+ (gps->dvert != NULL) ? dvert = gps->dvert : NULL;
+ for (i = 0, pt = gps->points; i < first; i++, pt++) {
+ *npt = *pt;
+ npt++;
+
+ if (gps->dvert != NULL) {
+ *ndvert = *dvert;
+ ndvert->dw = MEM_dupallocN(dvert->dw);
+ ndvert++;
+ dvert++;
+ }
+ }
+ /* copy segment (selected points) */
+ (gps->dvert != NULL) ? dvert = gps->dvert + first : NULL;
+ for (i = first, pt = gps->points + first; i < last; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ *npt = *pt;
+ npt++;
+
+ if (gps->dvert != NULL) {
+ *ndvert = *dvert;
+ ndvert->dw = MEM_dupallocN(dvert->dw);
+ ndvert++;
+ dvert++;
+ }
+ }
+ }
+ /* copy last segment */
+ (gps->dvert != NULL) ? dvert = gps->dvert + last : NULL;
+ for (i = last, pt = gps->points + last; i < gps->totpoints; i++, pt++) {
+ *npt = *pt;
+ npt++;
+
+ if (gps->dvert != NULL) {
+ *ndvert = *dvert;
+ ndvert->dw = MEM_dupallocN(dvert->dw);
+ ndvert++;
+ dvert++;
+ }
+ }
+
+ break;
+ case GP_DISSOLVE_UNSELECT:
+ /* copy any selected point */
+ (gps->dvert != NULL) ? dvert = gps->dvert : NULL;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ *npt = *pt;
+ npt++;
+
+ if (gps->dvert != NULL) {
+ *ndvert = *dvert;
+ ndvert->dw = MEM_dupallocN(dvert->dw);
+ ndvert++;
+ dvert++;
+ }
+ }
+ }
+ break;
+ }
- /* free the old buffer */
- MEM_freeN(gps->points);
+ /* free the old buffer */
+ if (gps->points) {
+ MEM_freeN(gps->points);
+ }
+ if (gps->dvert) {
+ BKE_gpencil_free_stroke_weights(gps);
+ MEM_freeN(gps->dvert);
+ }
- /* save the new buffer */
- gps->points = new_points;
- gps->totpoints = tot;
+ /* save the new buffer */
+ gps->points = new_points;
+ gps->dvert = new_dvert;
+ gps->totpoints = tot;
- /* triangles cache needs to be recalculated */
- gps->flag |= GP_STROKE_RECALC_CACHES;
- gps->tot_triangles = 0;
+ /* triangles cache needs to be recalculated */
+ gps->flag |= GP_STROKE_RECALC_CACHES;
+ gps->tot_triangles = 0;
- /* deselect the stroke, since none of its selected points will still be selected */
- gps->flag &= ~GP_STROKE_SELECT;
- }
+ /* deselect the stroke, since none of its selected points will still be selected */
+ gps->flag &= ~GP_STROKE_SELECT;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+ }
- changed = true;
+ changed = true;
+ }
+ }
}
}
}
CTX_DATA_END;
if (changed) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
@@ -1146,17 +1689,17 @@ typedef struct tGPDeleteIsland {
* becomes much less
* 2) Each island gets converted to a new stroke
*/
-void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, int tag_flags)
+void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke,
+ int tag_flags, bool select)
{
tGPDeleteIsland *islands = MEM_callocN(sizeof(tGPDeleteIsland) * (gps->totpoints + 1) / 2, "gp_point_islands");
bool in_island = false;
int num_islands = 0;
- bGPDspoint *pt;
- int i;
/* First Pass: Identify start/end of islands */
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ bGPDspoint *pt = gps->points;
+ for (int i = 0; i < gps->totpoints; i++, pt++) {
if (pt->flag & tag_flags) {
/* selected - stop accumulating to island */
in_island = false;
@@ -1198,11 +1741,26 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke
/* Compute new buffer size (+ 1 needed as the endpoint index is "inclusive") */
new_stroke->totpoints = island->end_idx - island->start_idx + 1;
- new_stroke->points = MEM_callocN(sizeof(bGPDspoint) * new_stroke->totpoints, "gp delete stroke fragment");
- /* Copy over the relevant points */
+ /* Copy over the relevant point data */
+ new_stroke->points = MEM_callocN(sizeof(bGPDspoint) * new_stroke->totpoints, "gp delete stroke fragment");
memcpy(new_stroke->points, gps->points + island->start_idx, sizeof(bGPDspoint) * new_stroke->totpoints);
+ /* Copy over vertex weight data (if available) */
+ if (new_stroke->dvert != NULL) {
+ /* Copy over the relevant vertex-weight points */
+ new_stroke->dvert = MEM_callocN(sizeof(MDeformVert) * new_stroke->totpoints, "gp delete stroke fragment weight");
+ memcpy(new_stroke->dvert, gps->dvert + island->start_idx, sizeof(MDeformVert) * new_stroke->totpoints);
+
+ /* Copy weights */
+ int e = island->start_idx;
+ for (int i = 0; i < new_stroke->totpoints; i++) {
+ MDeformVert *dvert_dst = &gps->dvert[e];
+ MDeformVert *dvert_src = &new_stroke->dvert[i];
+ dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
+ e++;
+ }
+ }
/* Each island corresponds to a new stroke. We must adjust the
* timings of these new strokes:
@@ -1222,6 +1780,11 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke
pts = new_stroke->points;
for (j = 0; j < new_stroke->totpoints; j++, pts++) {
pts->time -= delta;
+ /* set flag for select again later */
+ if (select == true) {
+ pts->flag &= ~GP_SPOINT_SELECT;
+ pts->flag |= GP_SPOINT_TAG;
+ }
}
}
@@ -1239,53 +1802,70 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke
MEM_freeN(islands);
/* Delete the old stroke */
- MEM_freeN(gps->points);
+ if (gps->points) {
+ MEM_freeN(gps->points);
+ }
+ if (gps->dvert) {
+ BKE_gpencil_free_stroke_weights(gps);
+ MEM_freeN(gps->dvert);
+ }
if (gps->triangles) {
MEM_freeN(gps->triangles);
}
BLI_freelinkN(&gpf->strokes, gps);
}
-
/* Split selected strokes into segments, splitting on selected points */
static int gp_delete_selected_points(bContext *C)
{
+ Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
bool changed = false;
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
- bGPDframe *gpf = gpl->actframe;
- bGPDstroke *gps, *gpsn;
+ bGPDframe *init_gpf = gpl->actframe;
+ if (is_multiedit) {
+ init_gpf = gpl->frames.first;
+ }
- if (gpf == NULL)
- continue;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ bGPDstroke *gps, *gpsn;
- /* simply delete strokes which are selected */
- for (gps = gpf->strokes.first; gps; gps = gpsn) {
- gpsn = gps->next;
+ if (gpf == NULL)
+ continue;
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false)
- continue;
- /* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false)
- continue;
+ /* simply delete strokes which are selected */
+ for (gps = gpf->strokes.first; gps; gps = gpsn) {
+ gpsn = gps->next;
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false)
+ continue;
- if (gps->flag & GP_STROKE_SELECT) {
- /* deselect old stroke, since it will be used as template for the new strokes */
- gps->flag &= ~GP_STROKE_SELECT;
- /* delete unwanted points by splitting stroke into several smaller ones */
- gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT);
+ if (gps->flag & GP_STROKE_SELECT) {
+ /* deselect old stroke, since it will be used as template for the new strokes */
+ gps->flag &= ~GP_STROKE_SELECT;
- changed = true;
+ /* delete unwanted points by splitting stroke into several smaller ones */
+ gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false);
+
+ changed = true;
+ }
+ }
}
}
}
CTX_DATA_END;
if (changed) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
@@ -1294,6 +1874,12 @@ static int gp_delete_selected_points(bContext *C)
}
}
+/* simple wrapper to external call */
+int gp_delete_selected_point_wrap(bContext *C)
+{
+ return gp_delete_selected_points(C);
+}
+
/* ----------------------------------- */
static int gp_delete_exec(bContext *C, wmOperator *op)
@@ -1344,24 +1930,37 @@ void GPENCIL_OT_delete(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_delete_types, 0, "Type", "Method used for deleting Grease Pencil data");
}
-static int gp_dissolve_exec(bContext *C, wmOperator *UNUSED(op))
+static int gp_dissolve_exec(bContext *C, wmOperator *op)
{
- return gp_dissolve_selected_points(C);
+ eGP_DissolveMode mode = RNA_enum_get(op->ptr, "type");
+
+ return gp_dissolve_selected_points(C, mode);
}
void GPENCIL_OT_dissolve(wmOperatorType *ot)
{
+ static EnumPropertyItem prop_gpencil_dissolve_types[] = {
+ { GP_DISSOLVE_POINTS, "POINTS", 0, "Dissolve", "Dissolve selected points" },
+ { GP_DISSOLVE_BETWEEN, "BETWEEN", 0, "Dissolve Between", "Dissolve points between selected points" },
+ { GP_DISSOLVE_UNSELECT, "UNSELECT", 0, "Dissolve Unselect", "Dissolve all unselected points" },
+ { 0, NULL, 0, NULL, NULL }
+ };
+
/* identifiers */
ot->name = "Dissolve";
ot->idname = "GPENCIL_OT_dissolve";
ot->description = "Delete selected points without splitting strokes";
/* callbacks */
+ ot->invoke = WM_menu_invoke;
ot->exec = gp_dissolve_exec;
ot->poll = gp_stroke_edit_poll;
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
+
+ /* props */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_dissolve_types, 0, "Type", "Method used for disolving Stroke points");
}
/* ****************** Snapping - Strokes <-> Cursor ************************ */
@@ -1384,6 +1983,8 @@ static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
RegionView3D *rv3d = CTX_wm_region_data(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C); \
+ Object *obact = CTX_data_active_object(C);
const float gridf = rv3d->gridview;
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
@@ -1392,10 +1993,8 @@ static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
bGPDframe *gpf = gpl->actframe;
float diff_mat[4][4];
- /* calculate difference matrix if parent object */
- if (gpl->parent != NULL) {
- ED_gpencil_parent_location(gpl, diff_mat);
- }
+ /* calculate difference matrix object */
+ ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat);
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
bGPDspoint *pt;
@@ -1405,37 +2004,32 @@ static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false)
+ if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false)
continue;
// TODO: if entire stroke is selected, offset entire stroke by same amount?
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
/* only if point is selected */
if (pt->flag & GP_SPOINT_SELECT) {
- if (gpl->parent == NULL) {
- pt->x = gridf * floorf(0.5f + pt->x / gridf);
- pt->y = gridf * floorf(0.5f + pt->y / gridf);
- pt->z = gridf * floorf(0.5f + pt->z / gridf);
- }
- else {
- /* apply parent transformations */
- float fpt[3];
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
+ /* apply parent transformations */
+ float fpt[3];
+ mul_v3_m4v3(fpt, diff_mat, &pt->x);
- fpt[0] = gridf * floorf(0.5f + fpt[0] / gridf);
- fpt[1] = gridf * floorf(0.5f + fpt[1] / gridf);
- fpt[2] = gridf * floorf(0.5f + fpt[2] / gridf);
+ fpt[0] = gridf * floorf(0.5f + fpt[0] / gridf);
+ fpt[1] = gridf * floorf(0.5f + fpt[1] / gridf);
+ fpt[2] = gridf * floorf(0.5f + fpt[2] / gridf);
- /* return data */
- copy_v3_v3(&pt->x, fpt);
- gp_apply_parent_point(gpl, pt);
- }
+ /* return data */
+ copy_v3_v3(&pt->x, fpt);
+ gp_apply_parent_point(depsgraph, obact, gpd, gpl, pt);
}
}
}
}
}
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ DEG_id_tag_update(&obact->id, DEG_TAG_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
@@ -1463,6 +2057,8 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C); \
+ Object *obact = CTX_data_active_object(C); \
const bool use_offset = RNA_boolean_get(op->ptr, "use_offset");
const float *cursor_global = ED_view3d_cursor3d_get(scene, v3d)->location;
@@ -1473,10 +2069,8 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op)
bGPDframe *gpf = gpl->actframe;
float diff_mat[4][4];
- /* calculate difference matrix if parent object */
- if (gpl->parent != NULL) {
- ED_gpencil_parent_location(gpl, diff_mat);
- }
+ /* calculate difference matrix */
+ ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat);
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
bGPDspoint *pt;
@@ -1486,7 +2080,7 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op)
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false)
+ if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false)
continue;
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
if ((gps->flag & GP_STROKE_SELECT) == 0)
@@ -1509,9 +2103,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);
- if (gpl->parent != NULL) {
- gp_apply_parent_point(gpl, pt);
- }
+ gp_apply_parent_point(depsgraph, obact, gpd, gpl, pt);
}
}
}
@@ -1520,6 +2112,8 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op)
}
}
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ DEG_id_tag_update(&obact->id, DEG_TAG_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
@@ -1551,6 +2145,8 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C); \
+ Object *obact = CTX_data_active_object(C); \
float *cursor = ED_view3d_cursor3d_get(scene, v3d)->location;
float centroid[3] = {0.0f};
@@ -1566,10 +2162,8 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
bGPDframe *gpf = gpl->actframe;
float diff_mat[4][4];
- /* calculate difference matrix if parent object */
- if (gpl->parent != NULL) {
- ED_gpencil_parent_location(gpl, diff_mat);
- }
+ /* calculate difference matrix */
+ ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat);
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
bGPDspoint *pt;
@@ -1579,7 +2173,7 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false)
+ if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false)
continue;
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
if ((gps->flag & GP_STROKE_SELECT) == 0)
@@ -1587,18 +2181,13 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (pt->flag & GP_SPOINT_SELECT) {
- if (gpl->parent == NULL) {
- add_v3_v3(centroid, &pt->x);
- minmax_v3v3_v3(min, max, &pt->x);
- }
- else {
- /* apply parent transformations */
- float fpt[3];
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
+ /* apply parent transformations */
+ float fpt[3];
+ mul_v3_m4v3(fpt, diff_mat, &pt->x);
add_v3_v3(centroid, fpt);
- minmax_v3v3_v3(min, max, fpt);
- }
+ minmax_v3v3_v3(min, max, fpt);
+
count++;
}
}
@@ -1616,7 +2205,9 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
}
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+
return OPERATOR_FINISHED;
}
@@ -1650,13 +2241,20 @@ static int gp_stroke_apply_thickness_exec(bContext *C, wmOperator *UNUSED(op))
for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
/* Apply thickness */
- gps->thickness = gps->thickness + gpl->thickness;
+ if ((gps->thickness == 0) && (gpl->line_change == 0)) {
+ gps->thickness = gpl->thickness;
+ }
+ else {
+ gps->thickness = gps->thickness + gpl->line_change;
+ }
}
}
/* clear value */
gpl->thickness = 0.0f;
+ gpl->line_change = 0;
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -1685,6 +2283,8 @@ enum {
static int gp_stroke_cyclical_set_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
+ Object *ob = CTX_data_active_object(C);
+
const int type = RNA_enum_get(op->ptr, "type");
/* sanity checks */
@@ -1698,13 +2298,13 @@ static int gp_stroke_cyclical_set_exec(bContext *C, wmOperator *op)
continue;
for (bGPDstroke *gps = gpl->actframe->strokes.last; gps; gps = gps->prev) {
- bGPDpalettecolor *palcolor = gps->palcolor;
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
/* skip strokes that are not selected or invalid for current view */
if (((gps->flag & GP_STROKE_SELECT) == 0) || ED_gpencil_stroke_can_use(C, gps) == false)
continue;
/* skip hidden or locked colors */
- if (!palcolor || (palcolor->flag & PC_COLOR_HIDE) || (palcolor->flag & PC_COLOR_LOCKED))
+ if (!gp_style || (gp_style->flag & GP_STYLE_COLOR_HIDE) || (gp_style->flag & GP_STYLE_COLOR_LOCKED))
continue;
switch (type) {
@@ -1729,6 +2329,7 @@ static int gp_stroke_cyclical_set_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -1809,15 +2410,18 @@ static void gpencil_flip_stroke(bGPDstroke *gps)
}
/* Helper: copy point between strokes */
-static void gpencil_stroke_copy_point(bGPDstroke *gps, bGPDspoint *point, float delta[3],
+static void gpencil_stroke_copy_point(bGPDstroke *gps, bGPDspoint *point, int idx, float delta[3],
float pressure, float strength, float deltatime)
{
bGPDspoint *newpoint;
gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1));
+ if (gps->dvert != NULL) {
+ gps->dvert = MEM_reallocN(gps->dvert, sizeof(MDeformVert) * (gps->totpoints + 1));
+ }
gps->totpoints++;
-
newpoint = &gps->points[gps->totpoints - 1];
+
newpoint->x = point->x * delta[0];
newpoint->y = point->y * delta[1];
newpoint->z = point->z * delta[2];
@@ -1825,6 +2429,14 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps, bGPDspoint *point, float
newpoint->pressure = pressure;
newpoint->strength = strength;
newpoint->time = point->time + deltatime;
+
+ if (gps->dvert != NULL) {
+ MDeformVert *dvert = &gps->dvert[idx];
+ MDeformVert *newdvert = &gps->dvert[gps->totpoints - 1];
+
+ newdvert->totweight = dvert->totweight;
+ newdvert->dw = MEM_dupallocN(dvert->dw);
+ }
}
/* Helper: join two strokes using the shortest distance (reorder stroke if necessary ) */
@@ -1870,18 +2482,18 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a, bGPDstroke *gps_b, co
/* 1st: add one tail point to start invisible area */
point = gps_a->points[gps_a->totpoints - 1];
deltatime = point.time;
- gpencil_stroke_copy_point(gps_a, &point, delta, 0.0f, 0.0f, 0.0f);
+ gpencil_stroke_copy_point(gps_a, &point, gps_a->totpoints - 1, delta, 0.0f, 0.0f, 0.0f);
/* 2nd: add one head point to finish invisible area */
point = gps_b->points[0];
- gpencil_stroke_copy_point(gps_a, &point, delta, 0.0f, 0.0f, deltatime);
+ gpencil_stroke_copy_point(gps_a, &point, 0, delta, 0.0f, 0.0f, deltatime);
}
/* 3rd: add all points */
for (i = 0, pt = gps_b->points; i < gps_b->totpoints && pt; i++, pt++) {
/* check if still room in buffer */
if (gps_a->totpoints <= GP_STROKE_BUFFER_MAX - 2) {
- gpencil_stroke_copy_point(gps_a, pt, delta, pt->pressure, pt->strength, deltatime);
+ gpencil_stroke_copy_point(gps_a, pt, i, delta, pt->pressure, pt->strength, deltatime);
}
}
}
@@ -1891,8 +2503,7 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op)
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *activegpl = BKE_gpencil_layer_getactive(gpd);
bGPDstroke *gps, *gpsn;
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette);
+ Object *ob = CTX_data_active_object(C);
bGPDframe *gpf_a = NULL;
bGPDstroke *stroke_a = NULL;
@@ -1928,7 +2539,7 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
continue;
}
@@ -1948,15 +2559,17 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op)
if (new_stroke == NULL) {
new_stroke = MEM_dupallocN(stroke_a);
new_stroke->points = MEM_dupallocN(stroke_a->points);
+ if (stroke_a->dvert != NULL) {
+ new_stroke->dvert = MEM_dupallocN(stroke_a->dvert);
+ BKE_gpencil_stroke_weights_duplicate(stroke_a, new_stroke);
+ }
new_stroke->triangles = NULL;
new_stroke->tot_triangles = 0;
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
/* if new, set current color */
if (type == GP_STROKE_JOINCOPY) {
- new_stroke->palcolor = palcolor;
- BLI_strncpy(new_stroke->colorname, palcolor->info, sizeof(new_stroke->colorname));
- new_stroke->flag |= GP_STROKE_RECALC_COLOR;
+ new_stroke->mat_nr = stroke_a->mat_nr;
}
}
@@ -1995,6 +2608,7 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op)
}
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -2030,6 +2644,7 @@ void GPENCIL_OT_stroke_join(wmOperatorType *ot)
static int gp_stroke_flip_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
+ Object *ob = CTX_data_active_object(C);
/* sanity checks */
if (ELEM(NULL, gpd))
@@ -2049,7 +2664,7 @@ static int gp_stroke_flip_exec(bContext *C, wmOperator *UNUSED(op))
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
continue;
}
@@ -2061,6 +2676,7 @@ static int gp_stroke_flip_exec(bContext *C, wmOperator *UNUSED(op))
CTX_DATA_END;
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -2084,33 +2700,42 @@ void GPENCIL_OT_stroke_flip(wmOperatorType *ot)
/* ***************** Reproject Strokes ********************** */
typedef enum eGP_ReprojectModes {
+ /* Axis (equal to lock axis) */
+ GP_REPROJECT_AXIS = 0,
/* On same plane, parallel to viewplane */
- GP_REPROJECT_PLANAR = 0,
+ GP_REPROJECT_PLANAR,
/* Reprojected on to the scene geometry */
GP_REPROJECT_SURFACE,
} eGP_ReprojectModes;
-static bool gp_strokes_reproject_poll(bContext *C)
-{
- /* 2 Requirements:
- * - 1) Editable GP data
- * - 2) 3D View only (2D editors don't have projection issues)
- */
- return (gp_stroke_edit_poll(C) && ED_operator_view3d_active(C));
-}
-
static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Object *ob = CTX_data_active_object(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+ View3D *v3d = sa->spacedata.first;
+
GP_SpaceConversion gsc = {NULL};
- eGP_ReprojectModes mode = RNA_boolean_get(op->ptr, "type");
+ eGP_ReprojectModes mode = RNA_enum_get(op->ptr, "type");
+
+ int lock_axis = ts->gp_sculpt.lock_axis;
+ float origin[3];
+
+ if ((mode == GP_REPROJECT_AXIS) && (lock_axis == GP_LOCKAXIS_NONE)) {
+ BKE_report(op->reports, RPT_ERROR, "To reproject by axis, a lock axis must be set before");
+ return OPERATOR_CANCELLED;
+ }
/* init space conversion stuff */
gp_point_conversion_init(C, &gsc);
/* init autodist for geometry projection */
if (mode == GP_REPROJECT_SURFACE) {
- struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
view3d_region_operator_needs_opengl(CTX_wm_window(C), gsc.ar);
ED_view3d_autodist_init(depsgraph, gsc.ar, CTX_wm_view3d(C), 0);
}
@@ -2127,9 +2752,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
/* Compute inverse matrix for unapplying parenting once instead of doing per-point */
/* TODO: add this bit to the iteration macro? */
- if (gpl->parent) {
- invert_m4_m4(inverse_diff_mat, diff_mat);
- }
+ invert_m4_m4(inverse_diff_mat, diff_mat);
/* Adjust each point */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
@@ -2140,19 +2763,28 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
* coordinates, resulting in lost precision, which in turn causes stairstepping
* artifacts in the final points.
*/
- if (gpl->parent == NULL) {
- gp_point_to_xy_fl(&gsc, gps, pt, &xy[0], &xy[1]);
- }
- else {
- bGPDspoint pt2;
- gp_point_to_parent_space(pt, diff_mat, &pt2);
- gp_point_to_xy_fl(&gsc, gps, &pt2, &xy[0], &xy[1]);
+ bGPDspoint pt2;
+ gp_point_to_parent_space(pt, diff_mat, &pt2);
+ gp_point_to_xy_fl(&gsc, gps, &pt2, &xy[0], &xy[1]);
+
+ /* Project stroke in the axis locked */
+ if (mode == GP_REPROJECT_AXIS) {
+ if (lock_axis > GP_LOCKAXIS_NONE) {
+ ED_gp_get_drawing_reference(v3d, scene, ob, gpl,
+ ts->gpencil_v3d_align, origin);
+ ED_gp_project_point_to_plane(ob, rv3d, origin,
+ lock_axis - 1, &pt2);
+
+ copy_v3_v3(&pt->x, &pt2.x);
+
+ /* apply parent again */
+ gp_apply_parent_point(depsgraph, ob, gpd, gpl, pt);
+ }
}
-
/* Project screenspace back to 3D space (from current perspective)
* so that all points have been treated the same way
*/
- if (mode == GP_REPROJECT_PLANAR) {
+ else if (mode == GP_REPROJECT_PLANAR) {
/* Planar - All on same plane parallel to the viewplane */
gp_point_xy_to_3d(&gsc, scene, xy, &pt->x);
}
@@ -2175,7 +2807,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
}
/* Unapply parent corrections */
- if (gpl->parent) {
+ if (mode != GP_REPROJECT_AXIS) {
mul_m4_v3(inverse_diff_mat, &pt->x);
}
}
@@ -2183,6 +2815,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
}
GP_EDITABLE_STROKES_END;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
@@ -2190,6 +2823,9 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
void GPENCIL_OT_reproject(wmOperatorType *ot)
{
static const EnumPropertyItem reproject_type[] = {
+ { GP_REPROJECT_AXIS, "AXIS", 0, "Axis",
+ "Reproject the strokes using the current lock axis configuration. This is the same projection using while"
+ "drawing new strokes" },
{GP_REPROJECT_PLANAR, "PLANAR", 0, "Planar",
"Reproject the strokes to end up on the same plane, as if drawn from the current viewpoint "
"using 'Cursor' Stroke Placement"},
@@ -2208,10 +2844,10 @@ void GPENCIL_OT_reproject(wmOperatorType *ot)
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = gp_strokes_reproject_exec;
- ot->poll = gp_strokes_reproject_poll;
+ ot->poll = gp_strokes_edit3d_poll;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", reproject_type, GP_REPROJECT_PLANAR, "Projection Type", "");
@@ -2229,7 +2865,7 @@ static int gp_count_subdivision_cuts(bGPDstroke *gps)
if (pt->flag & GP_SPOINT_SELECT) {
if (i + 1 < gps->totpoints) {
if (gps->points[i + 1].flag & GP_SPOINT_SELECT) {
- ++totnewpoints;
+ totnewpoints++;
}
}
}
@@ -2237,6 +2873,7 @@ static int gp_count_subdivision_cuts(bGPDstroke *gps)
return totnewpoints;
}
+
static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -2267,6 +2904,9 @@ static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op)
/* resize the points arrys */
gps->totpoints += totnewpoints;
gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints);
+ if (gps->dvert != NULL) {
+ gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints);
+ }
gps->flag |= GP_STROKE_RECALC_CACHES;
/* loop and interpolate */
@@ -2275,19 +2915,27 @@ static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op)
bGPDspoint *pt = &temp_points[i];
bGPDspoint *pt_final = &gps->points[i2];
+ MDeformVert *dvert_final = &gps->dvert[i2];
+
/* copy current point */
copy_v3_v3(&pt_final->x, &pt->x);
pt_final->pressure = pt->pressure;
pt_final->strength = pt->strength;
pt_final->time = pt->time;
pt_final->flag = pt->flag;
- ++i2;
+
+ dvert_final->totweight = 0;
+ dvert_final->dw = NULL;
+ i2++;
/* if next point is selected add a half way point */
if (pt->flag & GP_SPOINT_SELECT) {
if (i + 1 < oldtotpoints) {
if (temp_points[i + 1].flag & GP_SPOINT_SELECT) {
pt_final = &gps->points[i2];
+ if (gps->dvert != NULL) {
+ dvert_final = &gps->dvert[i2];
+ }
/* Interpolate all values */
bGPDspoint *next = &temp_points[i + 1];
interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f);
@@ -2296,7 +2944,11 @@ static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op)
CLAMP(pt_final->strength, GPENCIL_STRENGTH_MIN, 1.0f);
pt_final->time = interpf(pt->time, next->time, 0.5f);
pt_final->flag |= GP_SPOINT_SELECT;
- ++i2;
+
+ dvert_final->totweight = 0;
+ dvert_final->dw = NULL;
+
+ i2++;
}
}
}
@@ -2309,6 +2961,7 @@ static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op)
GP_EDITABLE_STROKES_END;
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -2328,7 +2981,7 @@ void GPENCIL_OT_stroke_subdivide(wmOperatorType *ot)
ot->poll = gp_active_layer_poll;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, 10, "Number of Cuts", "", 1, 5);
@@ -2336,3 +2989,414 @@ void GPENCIL_OT_stroke_subdivide(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+
+/* ** simplify stroke *** */
+static int gp_stroke_simplify_exec(bContext *C, wmOperator *op)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ float factor = RNA_float_get(op->ptr, "factor");
+
+ /* sanity checks */
+ if (ELEM(NULL, gpd))
+ return OPERATOR_CANCELLED;
+
+ /* Go through each editable + selected stroke */
+ GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
+ {
+ if (gps->flag & GP_STROKE_SELECT) {
+ /* simplify stroke using Ramer-Douglas-Peucker algorithm */
+ BKE_gpencil_simplify_stroke(gps, factor);
+ }
+ }
+ GP_EDITABLE_STROKES_END;
+
+ /* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_stroke_simplify(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Simplify Stroke";
+ ot->idname = "GPENCIL_OT_stroke_simplify";
+ ot->description = "Simplify selected stroked reducing number of points";
+
+ /* api callbacks */
+ ot->exec = gp_stroke_simplify_exec;
+ ot->poll = gp_active_layer_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, 100.0f, "Factor", "", 0.0f, 100.0f);
+ /* avoid re-using last var */
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+}
+
+/* ** simplify stroke using fixed algorith *** */
+static int gp_stroke_simplify_fixed_exec(bContext *C, wmOperator *op)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ int steps = RNA_int_get(op->ptr, "step");
+
+ /* sanity checks */
+ if (ELEM(NULL, gpd))
+ return OPERATOR_CANCELLED;
+
+ /* Go through each editable + selected stroke */
+ GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
+ {
+ if (gps->flag & GP_STROKE_SELECT) {
+ for (int i = 0; i < steps; i++) {
+ BKE_gpencil_simplify_fixed(gps);
+ }
+ }
+ }
+ GP_EDITABLE_STROKES_END;
+
+ /* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_stroke_simplify_fixed(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Simplify Fixed Stroke";
+ ot->idname = "GPENCIL_OT_stroke_simplify_fixed";
+ 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;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_int(ot->srna, "step", 1, 1, 100, "Steps", "Number of simplify steps", 1, 10);
+
+ /* avoid re-using last var */
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+}
+
+/* ***************** Separate Strokes ********************** */
+typedef enum eGP_SeparateModes {
+ /* Points */
+ GP_SEPARATE_POINT = 0,
+ /* Selected Strokes */
+ GP_SEPARATE_STROKE,
+ /* Current Layer */
+ GP_SEPARATE_LAYER,
+} eGP_SeparateModes;
+
+static int gp_stroke_separate_exec(bContext *C, wmOperator *op)
+{
+ Base *base_new;
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base_old = CTX_data_active_base(C);
+ bGPdata *gpd_src = ED_gpencil_data_get_active(C);
+ Object *ob = CTX_data_active_object(C);
+
+ Object *ob_dst = NULL;
+ bGPdata *gpd_dst = NULL;
+ bGPDlayer *gpl_dst = NULL;
+ bGPDframe *gpf_dst = NULL;
+ bGPDspoint *pt;
+ Material *ma = NULL;
+ int i, idx;
+
+ eGP_SeparateModes mode = RNA_enum_get(op->ptr, "mode");
+
+ /* sanity checks */
+ if (ELEM(NULL, gpd_src)) {
+ return OPERATOR_CANCELLED;
+ }
+ bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_src);
+
+ /* create a new object */
+ base_new = ED_object_add_duplicate(bmain, scene, view_layer, base_old, 0);
+ ob_dst = base_new->object;
+
+ /* create new grease pencil datablock */
+ // XXX: check usercounts
+ gpd_dst = BKE_gpencil_data_addnew(bmain, "GPencil");
+ ob_dst->data = (bGPdata *)gpd_dst;
+
+ int totslots = ob_dst->totcol;
+ int totadd = 0;
+
+ /* loop old datablock and separate parts */
+ if ((mode == GP_SEPARATE_POINT) || (mode == GP_SEPARATE_STROKE)) {
+ CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+ {
+ gpl_dst = NULL;
+ bGPDframe *init_gpf = gpl->actframe;
+ if (is_multiedit) {
+ init_gpf = gpl->frames.first;
+ }
+
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ bGPDstroke *gps, *gpsn;
+
+ if (gpf == NULL) {
+ continue;
+ }
+
+ gpf_dst = NULL;
+
+ for (gps = gpf->strokes.first; gps; gps = gpsn) {
+ gpsn = gps->next;
+
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ continue;
+ }
+ /* separate selected strokes */
+ if (gps->flag & GP_STROKE_SELECT) {
+ /* add layer if not created before */
+ if (gpl_dst == NULL) {
+ gpl_dst = BKE_gpencil_layer_addnew(gpd_dst, gpl->info, false);
+ }
+
+ /* add frame if not created before */
+ if (gpf_dst == NULL) {
+ gpf_dst = BKE_gpencil_layer_getframe(gpl_dst, gpf->framenum, GP_GETFRAME_ADD_NEW);
+ }
+
+ /* add duplicate materials */
+ ma = give_current_material(ob, gps->mat_nr + 1);
+ idx = BKE_gpencil_get_material_index(ob_dst, ma);
+ if (idx == 0) {
+
+ totadd++;
+ ob_dst->actcol = totadd;
+ ob_dst->totcol = totadd;
+
+ if (totadd > totslots) {
+ BKE_object_material_slot_add(bmain, ob_dst);
+ }
+
+ assign_material(bmain, ob_dst, ma, ob_dst->totcol, BKE_MAT_ASSIGN_USERPREF);
+ idx = totadd;
+ }
+
+ /* selected points mode */
+ if (mode == GP_SEPARATE_POINT) {
+ /* make copy of source stroke */
+ bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps);
+
+ /* reasign material */
+ gps_dst->mat_nr = idx - 1;
+
+ /* link to destination frame */
+ BLI_addtail(&gpf_dst->strokes, gps_dst);
+
+ /* Invert selection status of all points in destination stroke */
+ for (i = 0, pt = gps_dst->points; i < gps_dst->totpoints; i++, pt++) {
+ pt->flag ^= GP_SPOINT_SELECT;
+ }
+
+ /* delete selected points from destination stroke */
+ gp_stroke_delete_tagged_points(gpf_dst, gps_dst, NULL, GP_SPOINT_SELECT, false);
+
+ /* delete selected points from origin stroke */
+ gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false);
+ }
+ /* selected strokes mode */
+ else if (mode == GP_SEPARATE_STROKE) {
+ /* deselect old stroke */
+ gps->flag &= ~GP_STROKE_SELECT;
+ /* unlink from source frame */
+ BLI_remlink(&gpf->strokes, gps);
+ gps->prev = gps->next = NULL;
+ /* relink to destination frame */
+ BLI_addtail(&gpf_dst->strokes, gps);
+ /* reasign material */
+ gps->mat_nr = idx - 1;
+ }
+ }
+ }
+ }
+
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
+ }
+ }
+ }
+ CTX_DATA_END;
+ }
+ else if (mode == GP_SEPARATE_LAYER) {
+ bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
+ if (gpl) {
+ /* try to set a new active layer in source datablock */
+ if (gpl->prev) {
+ BKE_gpencil_layer_setactive(gpd_src, gpl->prev);
+ }
+ else if (gpl->next) {
+ BKE_gpencil_layer_setactive(gpd_src, gpl->next);
+ }
+ /* unlink from source datablock */
+ BLI_remlink(&gpd_src->layers, gpl);
+ gpl->prev = gpl->next = NULL;
+ /* relink to destination datablock */
+ BLI_addtail(&gpd_dst->layers, gpl);
+ }
+ }
+ DEG_id_tag_update(&gpd_src->id, OB_RECALC_OB | OB_RECALC_DATA);
+ DEG_id_tag_update(&gpd_dst->id, OB_RECALC_OB | OB_RECALC_DATA);
+
+ DEG_relations_tag_update(bmain);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_stroke_separate(wmOperatorType *ot)
+{
+ static const EnumPropertyItem separate_type[] = {
+ {GP_SEPARATE_POINT, "POINT", 0, "Selected Points", "Separate the selected points" },
+ {GP_SEPARATE_STROKE, "STROKE", 0, "Selected Strokes", "Separate the selected strokes"},
+ {GP_SEPARATE_LAYER, "LAYER", 0, "Active Layer", "Separate the strokes of the current layer" },
+ { 0, NULL, 0, NULL, NULL }
+ };
+
+ /* identifiers */
+ ot->name = "Separate Strokes";
+ ot->idname = "GPENCIL_OT_stroke_separate";
+ ot->description = "Separate the selected strokes or layer in a new grease pencil object";
+
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = gp_stroke_separate_exec;
+ ot->poll = gp_strokes_edit3d_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "mode", separate_type, GP_SEPARATE_POINT, "Mode", "");
+}
+
+/* ***************** Split Strokes ********************** */
+static int gp_stroke_split_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bGPDspoint *pt;
+ int i;
+
+ /* sanity checks */
+ if (ELEM(NULL, gpd)) {
+ return OPERATOR_CANCELLED;
+ }
+ bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+
+ /* loop strokes and split parts */
+ CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+ {
+ bGPDframe *init_gpf = gpl->actframe;
+ if (is_multiedit) {
+ init_gpf = gpl->frames.first;
+ }
+
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ bGPDstroke *gps, *gpsn;
+
+ if (gpf == NULL) {
+ continue;
+ }
+
+ for (gps = gpf->strokes.first; gps; gps = gpsn) {
+ gpsn = gps->next;
+
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ continue;
+ }
+ /* split selected strokes */
+ if (gps->flag & GP_STROKE_SELECT) {
+ /* make copy of source stroke */
+ bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps);
+
+ /* link to same frame */
+ BLI_addtail(&gpf->strokes, gps_dst);
+
+ /* invert selection status of all points in destination stroke */
+ for (i = 0, pt = gps_dst->points; i < gps_dst->totpoints; i++, pt++) {
+ pt->flag ^= GP_SPOINT_SELECT;
+ }
+
+ /* delete selected points from destination stroke */
+ gp_stroke_delete_tagged_points(gpf, gps_dst, NULL, GP_SPOINT_SELECT, true);
+
+ /* delete selected points from origin stroke */
+ gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false);
+ }
+ }
+ /* select again tagged points */
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ bGPDspoint *ptn = gps->points;
+ for (int i2 = 0; i2 < gps->totpoints; i2++, ptn++) {
+ if (ptn->flag & GP_SPOINT_TAG) {
+ ptn->flag |= GP_SPOINT_SELECT;
+ ptn->flag &= ~GP_SPOINT_TAG;
+ }
+ }
+ }
+ }
+
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_stroke_split(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Split Strokes";
+ ot->idname = "GPENCIL_OT_stroke_split";
+ ot->description = "Split selected points as new stroke on same frame";
+
+ /* callbacks */
+ ot->exec = gp_stroke_split_exec;
+ ot->poll = gp_strokes_edit3d_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
new file mode 100644
index 00000000000..c6df07ae83e
--- /dev/null
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -0,0 +1,1258 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2017, Blender Foundation, Joshua Leung
+ * This is a new part of Blender
+ *
+ * Contributor(s): Antonio Vazquez, Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/gpencil/gpencil_fill.c
+ * \ingroup edgpencil
+ */
+
+#include <stdio.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_stack.h"
+
+#include "BLT_translation.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_image_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_main.h"
+#include "BKE_brush.h"
+#include "BKE_image.h"
+#include "BKE_gpencil.h"
+#include "BKE_material.h"
+#include "BKE_context.h"
+#include "BKE_screen.h"
+#include "BKE_paint.h"
+
+#include "ED_gpencil.h"
+#include "ED_screen.h"
+#include "ED_space_api.h"
+#include "ED_view3d.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "GPU_immediate.h"
+#include "GPU_draw.h"
+#include "GPU_matrix.h"
+#include "GPU_framebuffer.h"
+
+#include "UI_interface.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "gpencil_intern.h"
+
+#define LEAK_HORZ 0
+#define LEAK_VERT 1
+
+
+/* Temporary fill operation data (op->customdata) */
+typedef struct tGPDfill {
+ struct Main *bmain;
+ struct Depsgraph *depsgraph;
+ struct wmWindow *win; /* window where painting originated */
+ struct Scene *scene; /* current scene from context */
+ struct Object *ob; /* current active gp object */
+ struct ScrArea *sa; /* area where painting originated */
+ struct RegionView3D *rv3d; /* region where painting originated */
+ struct View3D *v3d; /* view3 where painting originated */
+ struct ARegion *ar; /* region where painting originated */
+ struct bGPdata *gpd; /* current GP datablock */
+ struct Material *mat; /* current material */
+ struct bGPDlayer *gpl; /* layer */
+ struct bGPDframe *gpf; /* frame */
+
+ short flag; /* flags */
+ short oldkey; /* avoid too fast events */
+ bool on_back; /* send to back stroke */
+
+ int center[2]; /* mouse fill center position */
+ int sizex; /* windows width */
+ int sizey; /* window height */
+ int lock_axis; /* lock to viewport axis */
+
+ short fill_leak; /* number of pixel to consider the leak is too small (x 2) */
+ float fill_threshold; /* factor for transparency */
+ int fill_simplylvl; /* number of simplify steps */
+ int fill_draw_mode; /* boundary limits drawing mode */
+
+ short sbuffer_size; /* number of elements currently in cache */
+ void *sbuffer; /* temporary points */
+ float *depth_arr; /* depth array for reproject */
+
+ Image *ima; /* temp image */
+ BLI_Stack *stack; /* temp points data */
+ void *draw_handle_3d; /* handle for drawing strokes while operator is running 3d stuff */
+} 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],
+ bool cyclic, float ink[4], int flag, float thershold)
+{
+ bGPDspoint *points = gps->points;
+
+ Material *ma = tgpf->mat;
+ MaterialGPencilStyle *gp_style = ma->gp_style;
+
+ int totpoints = gps->totpoints;
+ float fpt[3];
+ float col[4];
+
+ copy_v4_v4(col, ink);
+
+ /* if cyclic needs more vertex */
+ int cyclic_add = (cyclic) ? 1 : 0;
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ /* draw stroke curve */
+ glLineWidth(1.0f);
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints + cyclic_add);
+ const bGPDspoint *pt = points;
+
+ for (int i = 0; i < totpoints; i++, pt++) {
+
+ if (flag & GP_BRUSH_FILL_HIDE) {
+ float alpha = gp_style->stroke_rgba[3] * pt->strength;
+ CLAMP(alpha, 0.0f, 1.0f);
+ col[3] = alpha <= thershold ? 0.0f : 1.0f;
+ }
+ else {
+ col[3] = 1.0f;
+ }
+ /* set point */
+ immAttrib4fv(color, col);
+ mul_v3_m4v3(fpt, diff_mat, &pt->x);
+ immVertex3fv(pos, fpt);
+ }
+
+ if (cyclic && totpoints > 2) {
+ /* draw line to first point to complete the cycle */
+ immAttrib4fv(color, col);
+ mul_v3_m4v3(fpt, diff_mat, &points->x);
+ immVertex3fv(pos, fpt);
+ }
+
+ immEnd();
+ immUnbindProgram();
+}
+
+/* loop all layers */
+static void gp_draw_datablock(tGPDfill *tgpf, float ink[4])
+{
+ /* duplicated: etempFlags */
+ enum {
+ GP_DRAWFILLS_NOSTATUS = (1 << 0), /* don't draw status info */
+ GP_DRAWFILLS_ONLY3D = (1 << 1), /* only draw 3d-strokes */
+ };
+
+ Object *ob = tgpf->ob;
+ bGPdata *gpd = tgpf->gpd;
+ int cfra_eval = (int)DEG_get_ctime(tgpf->depsgraph);
+
+ tGPDdraw tgpw;
+ tgpw.rv3d = tgpf->rv3d;
+ tgpw.depsgraph = tgpf->depsgraph;
+ tgpw.ob = ob;
+ tgpw.gpd = gpd;
+ tgpw.offsx = 0;
+ tgpw.offsy = 0;
+ tgpw.winx = tgpf->ar->winx;
+ tgpw.winy = tgpf->ar->winy;
+ tgpw.dflag = 0;
+ tgpw.disable_fill = 1;
+ tgpw.dflag |= (GP_DRAWFILLS_ONLY3D | GP_DRAWFILLS_NOSTATUS);
+
+ glEnable(GL_BLEND);
+
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ /* calculate parent position */
+ ED_gpencil_parent_location(tgpw.depsgraph, ob, gpd, gpl, tgpw.diff_mat);
+
+ /* do not draw layer if hidden */
+ if (gpl->flag & GP_LAYER_HIDE)
+ continue;
+
+ /* get frame to draw */
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0);
+ if (gpf == NULL)
+ continue;
+
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* check if stroke can be drawn */
+ if ((gps->points == NULL) || (gps->totpoints < 2)) {
+ continue;
+ }
+ /* check if the color is visible */
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
+ if ((gp_style == NULL) || (gp_style->flag & GP_STYLE_COLOR_HIDE)) {
+ continue;
+ }
+
+ tgpw.gps = gps;
+ tgpw.gpl = gpl;
+ tgpw.gpf = gpf;
+ tgpw.t_gpf = gpf;
+
+ /* reduce thickness to avoid gaps */
+ tgpw.lthick = gpl->line_change - 4;
+ tgpw.opacity = 1.0;
+ copy_v4_v4(tgpw.tintcolor, ink);
+ tgpw.onion = true;
+ tgpw.custonion = true;
+
+ /* normal strokes */
+ if ((tgpf->fill_draw_mode == GP_FILL_DMODE_STROKE) ||
+ (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH))
+ {
+ ED_gp_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);
+ }
+ }
+ }
+
+ glDisable(GL_BLEND);
+}
+
+ /* draw strokes in offscreen buffer */
+static void gp_render_offscreen(tGPDfill *tgpf)
+{
+ bool is_ortho = false;
+ float winmat[4][4];
+
+ if (!tgpf->gpd) {
+ return;
+ }
+
+ char err_out[256] = "unknown";
+ GPUOffScreen *offscreen = GPU_offscreen_create(tgpf->sizex, tgpf->sizey, 0, true, false, err_out);
+ GPU_offscreen_bind(offscreen, true);
+ uint flag = IB_rect | IB_rectfloat;
+ ImBuf *ibuf = IMB_allocImBuf(tgpf->sizex, tgpf->sizey, 32, flag);
+
+ rctf viewplane;
+ float clipsta, clipend;
+
+ is_ortho = ED_view3d_viewplane_get(tgpf->depsgraph, tgpf->v3d, tgpf->rv3d, tgpf->sizex, tgpf->sizey, &viewplane, &clipsta, &clipend, NULL);
+ if (is_ortho) {
+ orthographic_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, -clipend, clipend);
+ }
+ else {
+ perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+ }
+
+ /* set temporary new size */
+ int bwinx = tgpf->ar->winx;
+ int bwiny = tgpf->ar->winy;
+ rcti brect = tgpf->ar->winrct;
+
+ tgpf->ar->winx = (short) tgpf->sizex;
+ tgpf->ar->winy = (short) tgpf->sizey;
+ tgpf->ar->winrct.xmin = 0;
+ tgpf->ar->winrct.ymin = 0;
+ tgpf->ar->winrct.xmax = tgpf->sizex;
+ tgpf->ar->winrct.ymax = tgpf->sizey;
+
+ GPU_matrix_push_projection();
+ GPU_matrix_identity_set();
+ GPU_matrix_push();
+ GPU_matrix_identity_set();
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ ED_view3d_update_viewmat(
+ tgpf->depsgraph, tgpf->scene, tgpf->v3d, tgpf->ar,
+ NULL, winmat, NULL);
+ /* set for opengl */
+ GPU_matrix_projection_set(tgpf->rv3d->winmat);
+ GPU_matrix_set(tgpf->rv3d->viewmat);
+
+ /* draw strokes */
+ float ink[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
+ gp_draw_datablock(tgpf, ink);
+
+ /* restore size */
+ tgpf->ar->winx = (short)bwinx;
+ tgpf->ar->winy = (short)bwiny;
+ tgpf->ar->winrct = brect;
+
+ GPU_matrix_pop_projection();
+ GPU_matrix_pop();
+
+ /* create a image to see result of template */
+ if (ibuf->rect_float) {
+ GPU_offscreen_read_pixels(offscreen, GL_FLOAT, ibuf->rect_float);
+ }
+ else if (ibuf->rect) {
+ GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, ibuf->rect);
+ }
+ if (ibuf->rect_float && ibuf->rect) {
+ IMB_rect_from_float(ibuf);
+ }
+
+ tgpf->ima = BKE_image_add_from_imbuf(tgpf->bmain, ibuf, "GP_fill");
+ tgpf->ima->id.tag |= LIB_TAG_DOIT;
+
+ BKE_image_release_ibuf(tgpf->ima, ibuf, NULL);
+
+ /* switch back to window-system-provided framebuffer */
+ GPU_offscreen_unbind(offscreen, true);
+ GPU_offscreen_free(offscreen);
+}
+
+/* return pixel data (rgba) at index */
+static void get_pixel(ImBuf *ibuf, int idx, float r_col[4])
+{
+ if (ibuf->rect_float) {
+ float *frgba = &ibuf->rect_float[idx * 4];
+ copy_v4_v4(r_col, frgba);
+ }
+ else {
+ /* XXX: This case probably doesn't happen, as we only write to the float buffer,
+ * but we get compiler warnings about uninitialised vars otherwise
+ */
+ BLI_assert(!"gpencil_fill.c - get_pixel() non-float case is used!");
+ zero_v4(r_col);
+ }
+}
+
+/* set pixel data (rgba) at index */
+static void set_pixel(ImBuf *ibuf, int idx, const float col[4])
+{
+ //BLI_assert(idx <= ibuf->x * ibuf->y);
+ if (ibuf->rect) {
+ uint *rrect = &ibuf->rect[idx];
+ uchar ccol[4];
+
+ rgba_float_to_uchar(ccol, col);
+ *rrect = *((uint *)ccol);
+ }
+
+ if (ibuf->rect_float) {
+ float *rrectf = &ibuf->rect_float[idx * 4];
+ copy_v4_v4(rrectf, col);
+ }
+}
+
+/* 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 analize
+ * \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)
+{
+ float rgba[4];
+ int i;
+ int pt;
+ bool t_a = false;
+ bool t_b = false;
+
+ /* Horizontal leak (check vertical pixels)
+ * X
+ * X
+ * xB7
+ * X
+ * X
+ */
+ if (type == LEAK_HORZ) {
+ /* pixels on top */
+ for (i = 1; i <= limit; i++) {
+ pt = index + (ibuf->x * i);
+ if (pt <= maxpixel) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
+ t_a = true;
+ break;
+ }
+ }
+ else {
+ t_a = true; /* edge of image*/
+ break;
+ }
+ }
+ /* pixels on bottom */
+ for (i = 1; i <= limit; i++) {
+ pt = index - (ibuf->x * i);
+ if (pt >= 0) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
+ t_b = true;
+ break;
+ }
+ }
+ else {
+ t_b = true; /* edge of image*/
+ break;
+ }
+ }
+ }
+
+ /* Vertical leak (check horizontal pixels)
+ *
+ * XXXxB7XX
+ *
+ */
+ if (type == LEAK_VERT) {
+ /* get pixel range of the row */
+ int row = index / ibuf->x;
+ int lowpix = row * ibuf->x;
+ int higpix = lowpix + ibuf->x - 1;
+
+ /* pixels to right */
+ for (i = 0; i < limit; i++) {
+ pt = index - (limit - i);
+ if (pt >= lowpix) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
+ t_a = true;
+ break;
+ }
+ }
+ else {
+ t_a = true; /* edge of image*/
+ break;
+ }
+ }
+ /* pixels to left */
+ for (i = 0; i < limit; i++) {
+ pt = index + (limit - i);
+ if (pt <= higpix) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
+ t_b = true;
+ break;
+ }
+ }
+ else {
+ t_b = true; /* edge of image */
+ break;
+ }
+ }
+ }
+ return (bool)(t_a && t_b);
+}
+
+/* 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
+ */
+static void gpencil_boundaryfill_area(tGPDfill *tgpf)
+{
+ ImBuf *ibuf;
+ float rgba[4];
+ void *lock;
+ const float fill_col[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
+ ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
+ const int maxpixel = (ibuf->x * ibuf->y) - 1;
+
+ BLI_Stack *stack = BLI_stack_new(sizeof(int), __func__);
+
+ /* calculate index of the seed point using the position of the mouse */
+ int index = (tgpf->sizex * tgpf->center[1]) + tgpf->center[0];
+ if ((index >= 0) && (index < maxpixel)) {
+ BLI_stack_push(stack, &index);
+ }
+
+ /* the fill use a stack to save the pixel list instead of the common recursive
+ * 4-contact point method.
+ * The problem with recursive calls is that for big fill areas, we can get max limit
+ * of recursive calls and STACK_OVERFLOW error.
+ *
+ * The 4-contact point analyze the pixels to the left, right, bottom and top
+ * -----------
+ * | X |
+ * | XoX |
+ * | X |
+ * -----------
+ */
+ while (!BLI_stack_is_empty(stack)) {
+ int v;
+ BLI_stack_pop(stack, &v);
+
+ get_pixel(ibuf, v, rgba);
+
+ if (true) { /* Was: 'rgba' */
+ /* check if no border(red) or already filled color(green) */
+ if ((rgba[0] != 1.0f) && (rgba[1] != 1.0f)) {
+ /* fill current pixel */
+ set_pixel(ibuf, v, fill_col);
+
+ /* add contact pixels */
+ /* pixel left */
+ if (v - 1 >= 0) {
+ index = v - 1;
+ if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_HORZ)) {
+ BLI_stack_push(stack, &index);
+ }
+ }
+ /* pixel right */
+ if (v + 1 < maxpixel) {
+ index = v + 1;
+ if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_HORZ)) {
+ BLI_stack_push(stack, &index);
+ }
+ }
+ /* pixel top */
+ if (v + tgpf->sizex < maxpixel) {
+ index = v + tgpf->sizex;
+ if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_VERT)) {
+ BLI_stack_push(stack, &index);
+ }
+ }
+ /* pixel bottom */
+ if (v - tgpf->sizex >= 0) {
+ index = v - tgpf->sizex;
+ if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_VERT)) {
+ BLI_stack_push(stack, &index);
+ }
+ }
+ }
+ }
+ }
+
+ /* release ibuf */
+ if (ibuf) {
+ BKE_image_release_ibuf(tgpf->ima, ibuf, lock);
+ }
+
+ tgpf->ima->id.tag |= LIB_TAG_DOIT;
+ /* free temp stack data */
+ BLI_stack_free(stack);
+}
+
+/* clean external border of image to avoid infinite loops */
+static void gpencil_clean_borders(tGPDfill *tgpf)
+{
+ ImBuf *ibuf;
+ void *lock;
+ const float fill_col[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
+ int idx;
+ int pixel = 0;
+
+ /* horizontal lines */
+ for (idx = 0; idx < ibuf->x - 1; idx++) {
+ /* bottom line */
+ set_pixel(ibuf, idx, fill_col);
+ /* top line */
+ pixel = idx + (ibuf->x * (ibuf->y - 1));
+ set_pixel(ibuf, pixel, fill_col);
+ }
+ /* vertical lines */
+ for (idx = 0; idx < ibuf->y; idx++) {
+ /* left line */
+ set_pixel(ibuf, ibuf->x * idx, fill_col);
+ /* right line */
+ pixel = ibuf->x * idx + (ibuf->x - 1);
+ set_pixel(ibuf, pixel, fill_col);
+ }
+
+ /* release ibuf */
+ if (ibuf) {
+ BKE_image_release_ibuf(tgpf->ima, ibuf, lock);
+ }
+
+ tgpf->ima->id.tag |= LIB_TAG_DOIT;
+}
+
+/* Get the outline points of a shape using Moore Neighborhood algorithm
+ *
+ * This is a Blender customized version of the general algorithm described
+ * in https://en.wikipedia.org/wiki/Moore_neighborhood
+ */
+static void gpencil_get_outline_points(tGPDfill *tgpf)
+{
+ ImBuf *ibuf;
+ float rgba[4];
+ void *lock;
+ int v[2];
+ int boundary_co[2];
+ int start_co[2];
+ int backtracked_co[2];
+ int current_check_co[2];
+ int prev_check_co[2];
+ int backtracked_offset[1][2] = {{0, 0}};
+ // bool boundary_found = false;
+ bool start_found = false;
+ const int NEIGHBOR_COUNT = 8;
+
+ int offset[8][2] = {
+ { -1, -1 },
+ { 0, -1 },
+ { 1, -1 },
+ { 1, 0 },
+ { 1, 1 },
+ { 0, 1 },
+ { -1, 1 },
+ { -1, 0 }
+ };
+
+ tgpf->stack = BLI_stack_new(sizeof(int[2]), __func__);
+
+ ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
+ int imagesize = ibuf->x * ibuf->y;
+
+ /* find the initial point to start outline analysis */
+ for (int idx = imagesize; idx >= 0; idx--) {
+ get_pixel(ibuf, idx, rgba);
+ if (rgba[1] == 1.0f) {
+ boundary_co[0] = idx % ibuf->x;
+ boundary_co[1] = idx / ibuf->x;
+ copy_v2_v2_int(start_co, boundary_co);
+ backtracked_co[0] = (idx - 1) % ibuf->x;
+ backtracked_co[1] = (idx - 1) / ibuf->x;
+ backtracked_offset[0][0] = backtracked_co[0] - boundary_co[0];
+ backtracked_offset[0][1] = backtracked_co[1] - boundary_co[1];
+ copy_v2_v2_int(prev_check_co, start_co);
+
+ BLI_stack_push(tgpf->stack, &boundary_co);
+ start_found = true;
+ break;
+ }
+ }
+
+ while (start_found) {
+ int cur_back_offset = -1;
+ for (int i = 0; i < NEIGHBOR_COUNT; i++) {
+ if (backtracked_offset[0][0] == offset[i][0] &&
+ backtracked_offset[0][1] == offset[i][1])
+ {
+ /* Finding the bracktracked pixel offset index */
+ cur_back_offset = i;
+ break;
+ }
+ }
+
+ int loop = 0;
+ while (loop < (NEIGHBOR_COUNT - 1) && cur_back_offset != -1) {
+ int offset_idx = (cur_back_offset + 1) % NEIGHBOR_COUNT;
+ current_check_co[0] = boundary_co[0] + offset[offset_idx][0];
+ current_check_co[1] = boundary_co[1] + offset[offset_idx][1];
+
+ int image_idx = ibuf->x * current_check_co[1] + current_check_co[0];
+ get_pixel(ibuf, image_idx, rgba);
+
+ /* find next boundary pixel */
+ if (rgba[1] == 1.0f) {
+ copy_v2_v2_int(boundary_co, current_check_co);
+ copy_v2_v2_int(backtracked_co, prev_check_co);
+ backtracked_offset[0][0] = backtracked_co[0] - boundary_co[0];
+ backtracked_offset[0][1] = backtracked_co[1] - boundary_co[1];
+
+ BLI_stack_push(tgpf->stack, &boundary_co);
+
+ break;
+ }
+ copy_v2_v2_int(prev_check_co, current_check_co);
+ cur_back_offset++;
+ loop++;
+ }
+ /* current pixel is equal to starting pixel */
+ if (boundary_co[0] == start_co[0] &&
+ boundary_co[1] == start_co[1])
+ {
+ BLI_stack_pop(tgpf->stack, &v);
+ // boundary_found = true;
+ break;
+ }
+ }
+
+ /* release ibuf */
+ if (ibuf) {
+ BKE_image_release_ibuf(tgpf->ima, ibuf, lock);
+ }
+}
+
+/* get z-depth array to reproject on surface */
+static void gpencil_get_depth_array(tGPDfill *tgpf)
+{
+ tGPspoint *ptc;
+ ToolSettings *ts = tgpf->scene->toolsettings;
+ int totpoints = tgpf->sbuffer_size;
+ int i = 0;
+
+ if (totpoints == 0) {
+ return;
+ }
+
+ /* for surface sketching, need to set the right OpenGL context stuff so that
+ * the conversions will project the values correctly...
+ */
+ if (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_VIEW) {
+ /* need to restore the original projection settings before packing up */
+ view3d_region_operator_needs_opengl(tgpf->win, tgpf->ar);
+ ED_view3d_autodist_init(tgpf->depsgraph, tgpf->ar, tgpf->v3d, 0);
+
+ /* since strokes are so fine, when using their depth we need a margin otherwise they might get missed */
+ int depth_margin = 0;
+
+ /* get an array of depths, far depths are blended */
+ int mval[2], mval_prev[2] = { 0 };
+ int interp_depth = 0;
+ int found_depth = 0;
+
+ tgpf->depth_arr = MEM_mallocN(sizeof(float) * totpoints, "depth_points");
+
+ for (i = 0, ptc = tgpf->sbuffer; i < totpoints; i++, ptc++) {
+ copy_v2_v2_int(mval, &ptc->x);
+
+ if ((ED_view3d_autodist_depth(
+ tgpf->ar, mval, depth_margin, tgpf->depth_arr + i) == 0) &&
+ (i && (ED_view3d_autodist_depth_seg(
+ tgpf->ar, mval, mval_prev, depth_margin + 1, tgpf->depth_arr + i) == 0)))
+ {
+ interp_depth = true;
+ }
+ else {
+ found_depth = true;
+ }
+
+ copy_v2_v2_int(mval_prev, mval);
+ }
+
+ if (found_depth == false) {
+ /* eeh... not much we can do.. :/, ignore depth in this case */
+ for (i = totpoints - 1; i >= 0; i--)
+ tgpf->depth_arr[i] = 0.9999f;
+ }
+ else {
+ if (interp_depth) {
+ interp_sparse_array(tgpf->depth_arr, totpoints, FLT_MAX);
+ }
+ }
+ }
+}
+
+/* create array of points using stack as source */
+static void gpencil_points_from_stack(tGPDfill *tgpf)
+{
+ tGPspoint *point2D;
+ int totpoints = BLI_stack_count(tgpf->stack);
+ if (totpoints == 0) {
+ return;
+ }
+
+ tgpf->sbuffer_size = (short)totpoints;
+ tgpf->sbuffer = MEM_callocN(sizeof(tGPspoint) * totpoints, __func__);
+
+ point2D = tgpf->sbuffer;
+ while (!BLI_stack_is_empty(tgpf->stack)) {
+ int v[2];
+ BLI_stack_pop(tgpf->stack, &v);
+ point2D->x = v[0];
+ point2D->y = v[1];
+
+ point2D->pressure = 1.0f;
+ point2D->strength = 1.0f;;
+ point2D->time = 0.0f;
+ point2D++;
+ }
+}
+
+/* create a grease pencil stroke using points in buffer */
+static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
+{
+ ToolSettings *ts = tgpf->scene->toolsettings;
+ int cfra_eval = (int)DEG_get_ctime(tgpf->depsgraph);
+
+ Brush *brush;
+ brush = BKE_brush_getactive_gpencil(ts);
+ if (brush == NULL) {
+ return;
+ }
+
+ bGPDspoint *pt;
+ MDeformVert *dvert;
+ tGPspoint *point2D;
+
+ if (tgpf->sbuffer_size == 0) {
+ return;
+ }
+
+ /* get frame or create a new one */
+ tgpf->gpf = BKE_gpencil_layer_getframe(tgpf->gpl, cfra_eval, GP_GETFRAME_ADD_NEW);
+
+ /* create new stroke */
+ bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "bGPDstroke");
+ gps->thickness = brush->size;
+ gps->inittime = 0.0f;
+
+ /* the polygon must be closed, so enabled cyclic */
+ gps->flag |= GP_STROKE_CYCLIC;
+ gps->flag |= GP_STROKE_3DSPACE;
+
+ gps->mat_nr = BKE_gpencil_get_material_index(tgpf->ob, tgpf->mat) - 1;
+
+ /* allocate memory for storage points */
+ gps->totpoints = tgpf->sbuffer_size;
+ gps->points = MEM_callocN(sizeof(bGPDspoint) * tgpf->sbuffer_size, "gp_stroke_points");
+ gps->dvert = MEM_callocN(sizeof(MDeformVert) * tgpf->sbuffer_size, "gp_stroke_weights");
+
+ /* initialize triangle memory to dummy data */
+ gps->tot_triangles = 0;
+ gps->triangles = NULL;
+ gps->flag |= GP_STROKE_RECALC_CACHES;
+
+ /* add stroke to frame */
+ if ((ts->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK) || (tgpf->on_back == true)) {
+ BLI_addhead(&tgpf->gpf->strokes, gps);
+ }
+ else {
+ BLI_addtail(&tgpf->gpf->strokes, gps);
+ }
+
+ /* add points */
+ pt = gps->points;
+ dvert = gps->dvert;
+ point2D = (tGPspoint *)tgpf->sbuffer;
+ for (int i = 0; i < tgpf->sbuffer_size && point2D; i++, point2D++, pt++, dvert++) {
+ /* convert screen-coordinates to 3D coordinates */
+ gp_stroke_convertcoords_tpoint(
+ tgpf->scene, tgpf->ar, tgpf->v3d, tgpf->ob,
+ tgpf->gpl, point2D,
+ tgpf->depth_arr ? tgpf->depth_arr + i : NULL,
+ &pt->x);
+
+ pt->pressure = 1.0f;
+ pt->strength = 1.0f;;
+ pt->time = 0.0f;
+
+ dvert->totweight = 0;
+ dvert->dw = NULL;
+ }
+
+ /* smooth stroke */
+ float reduce = 0.0f;
+ float smoothfac = 1.0f;
+ for (int r = 0; r < 1; r++) {
+ for (int i = 0; i < gps->totpoints; i++) {
+ BKE_gpencil_smooth_stroke(gps, i, smoothfac - reduce);
+ }
+ reduce += 0.25f; // reduce the factor
+ }
+
+ /* if axis locked, reproject to plane locked */
+ if ((tgpf->lock_axis > GP_LOCKAXIS_NONE) && ((ts->gpencil_v3d_align & GP_PROJECT_DEPTH_VIEW) == 0)) {
+ float origin[3];
+ ED_gp_get_drawing_reference(tgpf->v3d, tgpf->scene, tgpf->ob, tgpf->gpl,
+ ts->gpencil_v3d_align, origin);
+ ED_gp_project_stroke_to_plane(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_size; a++) {
+ pt = &gps->points[a];
+ gp_apply_parent_point(tgpf->depsgraph, tgpf->ob, tgpf->gpd, tgpf->gpl, pt);
+ }
+
+ /* simplify stroke */
+ for (int b = 0; b < tgpf->fill_simplylvl; b++) {
+ BKE_gpencil_simplify_fixed(gps);
+ }
+}
+
+/* ----------------------- */
+/* Drawing */
+/* Helper: Draw status message while the user is running the operator */
+static void gpencil_fill_status_indicators(bContext *C, tGPDfill *UNUSED(tgpf))
+{
+ const char *status_str = IFACE_("Fill: ESC/RMB cancel, LMB Fill, Shift Draw on Back");
+ ED_workspace_status_text(C, status_str);
+}
+
+/* draw boundary lines to see fill limits */
+static void gpencil_draw_boundary_lines(const bContext *UNUSED(C), tGPDfill *tgpf)
+{
+ if (!tgpf->gpd) {
+ return;
+ }
+ float ink[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
+ gp_draw_datablock(tgpf, ink);
+}
+
+/* Drawing callback for modal operator in 3d mode */
+static void gpencil_fill_draw_3d(const bContext *C, ARegion *UNUSED(ar), void *arg)
+{
+ tGPDfill *tgpf = (tGPDfill *)arg;
+ /* draw only in the region that originated operator. This is required for multiwindow */
+ ARegion *ar = CTX_wm_region(C);
+ if (ar != tgpf->ar) {
+ return;
+ }
+
+ gpencil_draw_boundary_lines(C, tgpf);
+}
+
+/* check if context is suitable for filling */
+static bool gpencil_fill_poll(bContext *C)
+{
+ if (ED_operator_regionactive(C)) {
+ ScrArea *sa = CTX_wm_area(C);
+ if (sa->spacetype == SPACE_VIEW3D) {
+ return 1;
+ }
+ else {
+ CTX_wm_operator_poll_msg_set(C, "Active region not valid for filling operator");
+ return 0;
+ }
+ }
+ else {
+ CTX_wm_operator_poll_msg_set(C, "Active region not set");
+ return 0;
+ }
+}
+
+/* Allocate memory and initialize values */
+static tGPDfill *gp_session_init_fill(bContext *C, wmOperator *UNUSED(op))
+{
+ tGPDfill *tgpf = MEM_callocN(sizeof(tGPDfill), "GPencil Fill Data");
+
+ /* define initial values */
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ Main *bmain = CTX_data_main(C);
+
+ /* set current scene and window info */
+ tgpf->bmain = CTX_data_main(C);
+ tgpf->scene = CTX_data_scene(C);
+ tgpf->ob = CTX_data_active_object(C);
+ tgpf->sa = CTX_wm_area(C);
+ tgpf->ar = CTX_wm_region(C);
+ tgpf->rv3d = tgpf->ar->regiondata;
+ tgpf->v3d = tgpf->sa->spacedata.first;
+ tgpf->depsgraph = CTX_data_depsgraph(C);
+ tgpf->win = CTX_wm_window(C);
+
+ /* set GP datablock */
+ tgpf->gpd = gpd;
+ tgpf->gpl = BKE_gpencil_layer_getactive(gpd);
+ if (tgpf->gpl == NULL) {
+ tgpf->gpl = BKE_gpencil_layer_addnew(tgpf->gpd, DATA_("GP_Layer"), true);
+ }
+ tgpf->lock_axis = ts->gp_sculpt.lock_axis;
+
+ tgpf->oldkey = -1;
+ tgpf->sbuffer_size = 0;
+ tgpf->sbuffer = NULL;
+ tgpf->depth_arr = NULL;
+
+ /* save filling parameters */
+ Brush *brush = BKE_brush_getactive_gpencil(ts);
+ tgpf->flag = brush->gpencil_settings->flag;
+ tgpf->fill_leak = brush->gpencil_settings->fill_leak;
+ tgpf->fill_threshold = brush->gpencil_settings->fill_threshold;
+ tgpf->fill_simplylvl = brush->gpencil_settings->fill_simplylvl;
+ tgpf->fill_draw_mode = brush->gpencil_settings->fill_draw_mode;
+
+ /* get color info */
+ Material *ma = BKE_gpencil_get_material_from_brush(brush);
+ /* if no brush defaults, get material and color info */
+ if ((ma == NULL) || (ma->gp_style == NULL)) {
+ ma = BKE_gpencil_material_ensure(bmain, tgpf->ob);
+ /* assign always the first material to the brush */
+ brush->gpencil_settings->material = give_current_material(tgpf->ob, 1);
+ }
+
+ tgpf->mat = ma;
+
+ /* init undo */
+ gpencil_undo_init(tgpf->gpd);
+
+ /* return context data for running operator */
+ return tgpf;
+}
+
+/* end operator */
+static void gpencil_fill_exit(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob = CTX_data_active_object(C);
+
+ /* clear undo stack */
+ gpencil_undo_finish();
+
+ /* restore cursor to indicate end of fill */
+ WM_cursor_modal_restore(CTX_wm_window(C));
+
+ tGPDfill *tgpf = op->customdata;
+
+ /* don't assume that operator data exists at all */
+ if (tgpf) {
+ /* clear status message area */
+ ED_workspace_status_text(C, NULL);
+
+ MEM_SAFE_FREE(tgpf->sbuffer);
+ MEM_SAFE_FREE(tgpf->depth_arr);
+
+ /* remove drawing handler */
+ if (tgpf->draw_handle_3d) {
+ ED_region_draw_cb_exit(tgpf->ar->type, tgpf->draw_handle_3d);
+ }
+
+ /* delete temp image */
+ if (tgpf->ima) {
+ for (Image *ima = bmain->image.first; ima; ima = ima->id.next) {
+ if (ima == tgpf->ima) {
+ BLI_remlink(&bmain->image, ima);
+ BKE_image_free(tgpf->ima);
+ MEM_SAFE_FREE(tgpf->ima);
+ break;
+ }
+ }
+ }
+
+ /* finally, free memory used by temp data */
+ MEM_freeN(tgpf);
+ }
+
+ /* clear pointer */
+ op->customdata = NULL;
+
+ /* drawing batch cache is dirty now */
+ if ((ob) && (ob->type == OB_GPENCIL) && (ob->data)) {
+ bGPdata *gpd2 = ob->data;
+ DEG_id_tag_update(&gpd2->id, OB_RECALC_OB | OB_RECALC_DATA);
+ gpd2->flag |= GP_DATA_CACHE_IS_DIRTY;
+ }
+
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+}
+
+static void gpencil_fill_cancel(bContext *C, wmOperator *op)
+{
+ /* this is just a wrapper around exit() */
+ gpencil_fill_exit(C, op);
+}
+
+/* Init: Allocate memory and set init values */
+static int gpencil_fill_init(bContext *C, wmOperator *op)
+{
+ tGPDfill *tgpf;
+ /* cannot paint in locked layer */
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
+ if ((gpl) && (gpl->flag & GP_LAYER_LOCKED)) {
+ return 0;
+ }
+
+ /* check context */
+ tgpf = op->customdata = gp_session_init_fill(C, op);
+ if (tgpf == NULL) {
+ /* something wasn't set correctly in context */
+ gpencil_fill_exit(C, op);
+ return 0;
+ }
+
+ /* everything is now setup ok */
+ return 1;
+}
+
+/* start of interactive part of operator */
+static int gpencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ tGPDfill *tgpf = NULL;
+
+ /* try to initialize context data needed */
+ if (!gpencil_fill_init(C, op)) {
+ gpencil_fill_exit(C, op);
+ if (op->customdata)
+ MEM_freeN(op->customdata);
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ tgpf = op->customdata;
+ }
+
+ /* Enable custom drawing handlers to show help lines */
+ if (tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) {
+ tgpf->draw_handle_3d = ED_region_draw_cb_activate(tgpf->ar->type, gpencil_fill_draw_3d, tgpf, REGION_DRAW_POST_VIEW);
+ }
+
+ WM_cursor_modal_set(CTX_wm_window(C), BC_PAINTBRUSHCURSOR);
+
+ gpencil_fill_status_indicators(C, tgpf);
+
+ DEG_id_tag_update(&tgpf->gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+
+ /* add a modal handler for this operator*/
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* events handling during interactive part of operator */
+static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ tGPDfill *tgpf = op->customdata;
+
+ int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through */
+
+ switch (event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ estate = OPERATOR_CANCELLED;
+ break;
+ case LEFTMOUSE:
+ tgpf->on_back = RNA_boolean_get(op->ptr, "on_back");
+ /* first time the event is not enabled to show help lines */
+ if ((tgpf->oldkey != -1) || ((tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) == 0)) {
+ ARegion *ar = BKE_area_find_region_xy(CTX_wm_area(C), RGN_TYPE_ANY, event->x, event->y);
+ if (ar) {
+ bool in_bounds = false;
+
+ /* Perform bounds check */
+ in_bounds = BLI_rcti_isect_pt(&ar->winrct, event->x, event->y);
+
+ if ((in_bounds) && (ar->regiontype == RGN_TYPE_WINDOW)) {
+ /* TODO GPXX: Verify the mouse click is right for any window size */
+ tgpf->center[0] = event->mval[0];
+ tgpf->center[1] = event->mval[1];
+
+ /* save size */
+ tgpf->sizex = ar->winx;
+ tgpf->sizey = ar->winy;
+
+ /* render screen to temp image */
+ gp_render_offscreen(tgpf);
+
+ /* apply boundary fill */
+ gpencil_boundaryfill_area(tgpf);
+
+ /* clean borders to avoid infinite loops */
+ gpencil_clean_borders(tgpf);
+
+ /* analyze outline */
+ gpencil_get_outline_points(tgpf);
+
+ /* create array of points from stack */
+ gpencil_points_from_stack(tgpf);
+
+ /* create z-depth array for reproject */
+ gpencil_get_depth_array(tgpf);
+
+ /* create stroke and reproject */
+ gpencil_stroke_from_buffer(tgpf);
+
+ /* free temp stack data */
+ if (tgpf->stack) {
+ BLI_stack_free(tgpf->stack);
+ }
+
+ /* push undo data */
+ gpencil_undo_push(tgpf->gpd);
+
+ estate = OPERATOR_FINISHED;
+ }
+ else {
+ estate = OPERATOR_CANCELLED;
+ }
+ }
+ else {
+ estate = OPERATOR_CANCELLED;
+ }
+ }
+ tgpf->oldkey = event->type;
+ break;
+ }
+ /* process last operations before exiting */
+ switch (estate) {
+ case OPERATOR_FINISHED:
+ gpencil_fill_exit(C, op);
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+ break;
+
+ case OPERATOR_CANCELLED:
+ gpencil_fill_exit(C, op);
+ break;
+
+ case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH:
+ break;
+ }
+
+ /* return status code */
+ return estate;
+}
+
+void GPENCIL_OT_fill(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Grease Pencil Fill";
+ ot->idname = "GPENCIL_OT_fill";
+ ot->description = "Fill with color the shape formed by strokes";
+
+ /* api callbacks */
+ ot->invoke = gpencil_fill_invoke;
+ ot->modal = gpencil_fill_modal;
+ ot->poll = gpencil_fill_poll;
+ ot->cancel = gpencil_fill_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
+
+ prop = RNA_def_boolean(ot->srna, "on_back", false, "Draw On Back", "Send new stroke to Back");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+}
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 90ff1e0bb25..52e7d1e1f30 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -34,25 +34,145 @@
#include "DNA_vec_types.h"
+#include "ED_numinput.h"
+
/* internal exports only */
struct bGPdata;
struct bGPDstroke;
struct bGPDspoint;
+struct tGPspoint;
+struct Material;
struct GHash;
struct RNG;
+struct Brush;
+struct Scene;
struct ARegion;
+struct View3D;
struct View2D;
struct wmOperatorType;
+struct Depsgraph;
+
struct PointerRNA;
struct PropertyRNA;
struct EnumPropertyItem;
/* ***************************************************** */
+/* Modal Operator Geometry Preview
+ *
+ * Several modal operators (Fill, Interpolate, Primitive)
+ * need to run some drawing code to display previews, or
+ * to perform screen-space/image-based analysis routines.
+ * The following structs + function prototypes are used
+ * by these operators so that the operator code
+ * (in gpencil_<opname>.c) can communicate with the drawing
+ * code (in drawgpencil.c).
+ *
+ * NOTE: All this is within the gpencil module, so nothing needs
+ * to be exported to other modules.
+ */
+
+/* Internal Operator-State Data ------------------------ */
+
+/* Temporary draw data (no draw manager mode) */
+typedef struct tGPDdraw {
+ struct RegionView3D *rv3d; /* region to draw */
+ struct Depsgraph *depsgraph; /* depsgraph */
+ struct Object *ob; /* GP object */
+ struct bGPdata *gpd; /* current GP datablock */
+ struct bGPDlayer *gpl; /* layer */
+ struct bGPDframe *gpf; /* frame */
+ struct bGPDframe *t_gpf; /* temporal frame */
+ struct bGPDstroke *gps; /* stroke */
+ int disable_fill; /* disable fill */
+ int offsx; /* windows offset x */
+ int offsy; /* windows offset y */
+ int winx; /* windows width */
+ int winy; /* windows height */
+ int dflag; /* flags datablock */
+ short lthick; /* layer thickness */
+ float opacity; /* opacity */
+ float tintcolor[4]; /* tint color */
+ bool onion; /* onion flag */
+ bool custonion; /* use custom onion colors */
+ float diff_mat[4][4]; /* matrix */
+} tGPDdraw;
+
+
+/* Temporary interpolate operation data */
+typedef struct tGPDinterpolate_layer {
+ struct tGPDinterpolate_layer *next, *prev;
+
+ struct bGPDlayer *gpl; /* layer */
+ struct bGPDframe *prevFrame; /* frame before current frame (interpolate-from) */
+ struct bGPDframe *nextFrame; /* frame after current frame (interpolate-to) */
+ struct bGPDframe *interFrame; /* interpolated frame */
+ float factor; /* interpolate factor */
+
+} tGPDinterpolate_layer;
+
+typedef struct tGPDinterpolate {
+ struct Scene *scene; /* current scene from context */
+ struct ScrArea *sa; /* area where painting originated */
+ struct ARegion *ar; /* region where painting originated */
+ struct bGPdata *gpd; /* current GP datablock */
+ struct Material *mat; /* current material */
+
+ int cframe; /* current frame number */
+ ListBase ilayers; /* (tGPDinterpolate_layer) layers to be interpolated */
+ float shift; /* value for determining the displacement influence */
+ float init_factor; /* initial interpolation factor for active layer */
+ float low_limit; /* shift low limit (-100%) */
+ float high_limit; /* shift upper limit (200%) */
+ int flag; /* flag from toolsettings */
+
+ NumInput num; /* numeric input */
+ void *draw_handle_3d; /* handle for drawing strokes while operator is running 3d stuff */
+ void *draw_handle_screen; /* handle for drawing strokes while operator is running screen stuff */
+} tGPDinterpolate;
+
+
+/* Temporary primitive operation data */
+typedef struct tGPDprimitive {
+ struct Depsgraph *depsgraph;
+ struct wmWindow *win; /* window where painting originated */
+ struct Scene *scene; /* current scene from context */
+ struct Object *ob; /* current active gp object */
+ struct ScrArea *sa; /* area where painting originated */
+ struct RegionView3D *rv3d; /* region where painting originated */
+ struct View3D *v3d; /* view3d where painting originated */
+ struct ARegion *ar; /* region where painting originated */
+ struct bGPdata *gpd; /* current GP datablock */
+ struct Material *mat; /* current material */
+ struct Brush *brush; /* current brush */
+
+ int cframe; /* current frame number */
+ struct bGPDlayer *gpl; /* layer */
+ struct bGPDframe *gpf; /* frame */
+ int type; /* type of primitive */
+ int tot_edges; /* number of polygon edges */
+ int top[2]; /* first box corner */
+ int bottom[2]; /* last box corner */
+ int flag; /* flag to determine operations in progress */
+
+ int lock_axis; /* lock to viewport axis */
+
+ NumInput num; /* numeric input */
+ void *draw_handle_3d; /* handle for drawing strokes while operator is running 3d stuff */
+} tGPDprimitive;
+
+
+/* Modal Operator Drawing Callbacks ------------------------ */
+
+void ED_gp_draw_interpolation(const struct bContext *C, struct tGPDinterpolate *tgpi, const int type);
+void ED_gp_draw_primitives(const struct bContext *C, struct tGPDprimitive *tgpi, const int type);
+void ED_gp_draw_fill(struct tGPDdraw *tgpw);
+
+/* ***************************************************** */
/* Internal API */
/* Stroke Coordinates API ------------------------------ */
@@ -84,21 +204,30 @@ void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
float *r_x, float *r_y);
void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt);
-
-void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps);
-
-void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt);
+/**
+ * Change points position relative to parent object
+ */
+void gp_apply_parent(struct Depsgraph *depsgraph, struct Object *obact, bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps);
+/**
+ * Change point position relative to parent object
+ */
+void gp_apply_parent_point(struct Depsgraph *depsgraph, struct Object *obact, bGPdata *gpd, bGPDlayer *gpl, bGPDspoint *pt);
bool gp_point_xy_to_3d(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 *ar,
+ struct View3D *v3d, struct Object *ob,
+ bGPDlayer *gpl, 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_active_palette_poll(struct bContext *C);
-bool gp_active_palettecolor_poll(struct bContext *C);
bool gp_brush_crt_presets_poll(bContext *C);
/* Copy/Paste Buffer --------------------------------- */
@@ -107,18 +236,20 @@ bool gp_brush_crt_presets_poll(bContext *C);
extern ListBase gp_strokes_copypastebuf;
/* Build a map for converting between old colornames and destination-color-refs */
-struct GHash *gp_copybuf_validate_colormap(bGPdata *gpd);
+struct GHash *gp_copybuf_validate_colormap(struct bContext *C);
/* Stroke Editing ------------------------------------ */
-void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, int tag_flags);
-
+void gp_stroke_delete_tagged_points(
+ bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke,
+ int tag_flags, bool select);
+int gp_delete_selected_point_wrap(bContext *C);
bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure);
bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf);
bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf);
-void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints);
-void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush, struct RNG *rng);
+void gp_subdivide_stroke(bGPDstroke *gps, const int subdivide);
+void gp_randomize_stroke(bGPDstroke *gps, Brush *brush, struct RNG *rng);
/* Layers Enums -------------------------------------- */
@@ -129,22 +260,18 @@ const struct EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(
struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
bool *r_free);
-/* Enums of GP Brushes */
-const EnumPropertyItem *ED_gpencil_brushes_enum_itemf(
- bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
- bool *r_free);
-
-/* Enums of GP palettes */
-const EnumPropertyItem *ED_gpencil_palettes_enum_itemf(
- bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
- bool *r_free);
-
/* ***************************************************** */
/* Operator Defines */
+/* annotations ------ */
+
+void GPENCIL_OT_annotate(struct wmOperatorType *ot);
+
+
/* drawing ---------- */
void GPENCIL_OT_draw(struct wmOperatorType *ot);
+void GPENCIL_OT_fill(struct wmOperatorType *ot);
/* Paint Modes for operator */
typedef enum eGPencil_PaintModes {
@@ -160,6 +287,9 @@ typedef enum eGPencil_PaintModes {
/* stroke editing ----- */
void GPENCIL_OT_editmode_toggle(struct wmOperatorType *ot);
+void GPENCIL_OT_paintmode_toggle(struct wmOperatorType *ot);
+void GPENCIL_OT_sculptmode_toggle(struct wmOperatorType *ot);
+void GPENCIL_OT_weightmode_toggle(struct wmOperatorType *ot);
void GPENCIL_OT_selection_opacity_toggle(struct wmOperatorType *ot);
void GPENCIL_OT_select(struct wmOperatorType *ot);
@@ -174,6 +304,7 @@ void GPENCIL_OT_select_more(struct wmOperatorType *ot);
void GPENCIL_OT_select_less(struct wmOperatorType *ot);
void GPENCIL_OT_select_first(struct wmOperatorType *ot);
void GPENCIL_OT_select_last(struct wmOperatorType *ot);
+void GPENCIL_OT_select_alternate(struct wmOperatorType *ot);
void GPENCIL_OT_duplicate(struct wmOperatorType *ot);
void GPENCIL_OT_delete(struct wmOperatorType *ot);
@@ -218,6 +349,8 @@ void GPENCIL_OT_blank_frame_add(struct wmOperatorType *ot);
void GPENCIL_OT_active_frame_delete(struct wmOperatorType *ot);
void GPENCIL_OT_active_frames_delete_all(struct wmOperatorType *ot);
+void GPENCIL_OT_frame_duplicate(struct wmOperatorType *ot);
+void GPENCIL_OT_frame_clean_fill(struct wmOperatorType *ot);
void GPENCIL_OT_convert(struct wmOperatorType *ot);
@@ -226,6 +359,13 @@ enum {
GP_STROKE_JOINCOPY = 1
};
+enum {
+ GP_STROKE_BOX = -1,
+ GP_STROKE_LINE = 1,
+ GP_STROKE_CIRCLE = 2
+};
+
+
void GPENCIL_OT_stroke_arrange(struct wmOperatorType *ot);
void GPENCIL_OT_stroke_change_color(struct wmOperatorType *ot);
void GPENCIL_OT_stroke_lock_color(struct wmOperatorType *ot);
@@ -234,30 +374,15 @@ void GPENCIL_OT_stroke_cyclical_set(struct wmOperatorType *ot);
void GPENCIL_OT_stroke_join(struct wmOperatorType *ot);
void GPENCIL_OT_stroke_flip(struct wmOperatorType *ot);
void GPENCIL_OT_stroke_subdivide(struct wmOperatorType *ot);
+void GPENCIL_OT_stroke_simplify(struct wmOperatorType *ot);
+void GPENCIL_OT_stroke_simplify_fixed(struct wmOperatorType *ot);
+void GPENCIL_OT_stroke_separate(struct wmOperatorType *ot);
+void GPENCIL_OT_stroke_split(struct wmOperatorType *ot);
-void GPENCIL_OT_brush_add(struct wmOperatorType *ot);
-void GPENCIL_OT_brush_remove(struct wmOperatorType *ot);
-void GPENCIL_OT_brush_change(struct wmOperatorType *ot);
-void GPENCIL_OT_brush_move(struct wmOperatorType *ot);
void GPENCIL_OT_brush_presets_create(struct wmOperatorType *ot);
-void GPENCIL_OT_brush_copy(struct wmOperatorType *ot);
void GPENCIL_OT_brush_select(struct wmOperatorType *ot);
-void GPENCIL_OT_palette_add(struct wmOperatorType *ot);
-void GPENCIL_OT_palette_remove(struct wmOperatorType *ot);
-void GPENCIL_OT_palette_change(struct wmOperatorType *ot);
-void GPENCIL_OT_palette_lock_layer(struct wmOperatorType *ot);
-
-void GPENCIL_OT_palettecolor_add(struct wmOperatorType *ot);
-void GPENCIL_OT_palettecolor_remove(struct wmOperatorType *ot);
-void GPENCIL_OT_palettecolor_isolate(struct wmOperatorType *ot);
-void GPENCIL_OT_palettecolor_hide(struct wmOperatorType *ot);
-void GPENCIL_OT_palettecolor_reveal(struct wmOperatorType *ot);
-void GPENCIL_OT_palettecolor_lock_all(struct wmOperatorType *ot);
-void GPENCIL_OT_palettecolor_unlock_all(struct wmOperatorType *ot);
-void GPENCIL_OT_palettecolor_move(struct wmOperatorType *ot);
-void GPENCIL_OT_palettecolor_select(struct wmOperatorType *ot);
-void GPENCIL_OT_palettecolor_copy(struct wmOperatorType *ot);
+void GPENCIL_OT_sculpt_select(struct wmOperatorType *ot);
/* undo stack ---------- */
@@ -271,6 +396,30 @@ void GPENCIL_OT_interpolate(struct wmOperatorType *ot);
void GPENCIL_OT_interpolate_sequence(struct wmOperatorType *ot);
void GPENCIL_OT_interpolate_reverse(struct wmOperatorType *ot);
+/* primitives ---------- */
+
+void GPENCIL_OT_primitive(struct wmOperatorType *ot);
+
+/* vertex groups ------------ */
+void GPENCIL_OT_vertex_group_assign(struct wmOperatorType *ot);
+void GPENCIL_OT_vertex_group_remove_from(struct wmOperatorType *ot);
+void GPENCIL_OT_vertex_group_select(struct wmOperatorType *ot);
+void GPENCIL_OT_vertex_group_deselect(struct wmOperatorType *ot);
+void GPENCIL_OT_vertex_group_invert(struct wmOperatorType *ot);
+void GPENCIL_OT_vertex_group_smooth(struct wmOperatorType *ot);
+
+/* color handle */
+void GPENCIL_OT_lock_layer(struct wmOperatorType *ot);
+void GPENCIL_OT_color_isolate(struct wmOperatorType *ot);
+void GPENCIL_OT_color_hide(struct wmOperatorType *ot);
+void GPENCIL_OT_color_reveal(struct wmOperatorType *ot);
+void GPENCIL_OT_color_lock_all(struct wmOperatorType *ot);
+void GPENCIL_OT_color_unlock_all(struct wmOperatorType *ot);
+void GPENCIL_OT_color_select(struct wmOperatorType *ot);
+
+/* convert old 2.7 files to 2.8 */
+void GPENCIL_OT_convert_old_files(struct wmOperatorType *ot);
+
/* ****************************************************** */
/* FILTERED ACTION DATA - TYPES ---> XXX DEPRECEATED OLD ANIM SYSTEM CODE! */
@@ -331,24 +480,37 @@ typedef enum ACTCONT_TYPES {
*/
#define GP_EDITABLE_STROKES_BEGIN(C, gpl, gps) \
{ \
+ Depsgraph *depsgraph_ = CTX_data_depsgraph(C); \
+ Object *obact_ = CTX_data_active_object(C); \
+ bGPdata *gpd_ = CTX_data_gpencil_data(C); \
+ bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_); \
CTX_DATA_BEGIN(C, bGPDlayer*, gpl, editable_gpencil_layers) \
{ \
- if (gpl->actframe == NULL) \
- continue; \
- /* calculate difference matrix if parent object */ \
- float diff_mat[4][4]; \
- ED_gpencil_parent_location(gpl, diff_mat); \
- /* loop over strokes */ \
- for (bGPDstroke *gps = gpl->actframe->strokes.first; gps; gps = gps->next) { \
- /* skip strokes that are invalid for current view */ \
- if (ED_gpencil_stroke_can_use(C, gps) == false) \
- continue; \
- /* check if the color is editable */ \
- if (ED_gpencil_stroke_color_use(gpl, gps) == false) \
- continue; \
- /* ... Do Stuff With Strokes ... */
+ bGPDframe *init_gpf = gpl->actframe; \
+ if (is_multiedit) { \
+ init_gpf = gpl->frames.first; \
+ } \
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { \
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { \
+ /* calculate difference matrix */ \
+ float diff_mat[4][4]; \
+ ED_gpencil_parent_location(depsgraph_, obact_, gpd_, gpl, diff_mat); \
+ /* loop over strokes */ \
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { \
+ /* skip strokes that are invalid for current view */ \
+ if (ED_gpencil_stroke_can_use(C, gps) == false) \
+ continue; \
+ /* check if the color is editable */ \
+ if (ED_gpencil_stroke_color_use(obact_, gpl, gps) == false) \
+ continue; \
+ /* ... Do Stuff With Strokes ... */
#define GP_EDITABLE_STROKES_END \
+ } \
+ } \
+ if (!is_multiedit) { \
+ break; \
+ } \
} \
} \
CTX_DATA_END; \
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index cc30d7ec266..6541e9f012a 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -47,6 +47,7 @@
#include "DNA_color_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -60,6 +61,7 @@
#include "BKE_library.h"
#include "BKE_report.h"
#include "BKE_screen.h"
+#include "BKE_deform.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -79,6 +81,9 @@
#include "ED_view3d.h"
#include "ED_space_api.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
#include "gpencil_intern.h"
/* ************************************************ */
@@ -108,11 +113,13 @@ static bool gpencil_view3d_poll(bContext *C)
static void gp_interpolate_update_points(bGPDstroke *gps_from, bGPDstroke *gps_to, bGPDstroke *new_stroke, float factor)
{
bGPDspoint *prev, *pt, *next;
+ MDeformVert *dvert;
/* update points */
for (int i = 0; i < new_stroke->totpoints; i++) {
prev = &gps_from->points[i];
pt = &new_stroke->points[i];
+ dvert = &new_stroke->dvert[i];
next = &gps_to->points[i];
/* Interpolate all values */
@@ -120,6 +127,9 @@ static void gp_interpolate_update_points(bGPDstroke *gps_from, bGPDstroke *gps_t
pt->pressure = interpf(prev->pressure, next->pressure, 1.0f - factor);
pt->strength = interpf(prev->strength, next->strength, 1.0f - factor);
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
+
+ dvert->totweight = 0;
+ dvert->dw = NULL;
}
}
@@ -128,6 +138,7 @@ static void gp_interpolate_update_points(bGPDstroke *gps_from, bGPDstroke *gps_t
/* Helper: Update all strokes interpolated */
static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi)
{
+ bGPdata *gpd = tgpi->gpd;
tGPDinterpolate_layer *tgpil;
const float shift = tgpi->shift;
@@ -156,12 +167,14 @@ static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi)
}
}
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
}
/* Helper: Verify valid strokes for interpolation */
static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd)
{
+ Object *ob = CTX_data_active_object(C);
ToolSettings *ts = CTX_data_tool_settings(C);
eGP_Interpolate_SettingsFlag flag = ts->gp_interpolate.flag;
@@ -190,7 +203,7 @@ static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
continue;
}
@@ -213,6 +226,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
bGPdata *gpd = tgpi->gpd;
bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C);
bGPDframe *actframe = active_gpl->actframe;
+ Object *ob = CTX_data_active_object(C);
/* save initial factor for active layer to define shift limits */
tgpi->init_factor = (float)(tgpi->cframe - actframe->framenum) / (actframe->next->framenum - actframe->framenum + 1);
@@ -255,7 +269,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
bGPDstroke *gps_to;
int fFrame;
- bGPDstroke *new_stroke;
+ bGPDstroke *new_stroke = NULL;
bool valid = true;
@@ -269,7 +283,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(tgpil->gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_color_use(ob, tgpil->gpl, gps_from) == false) {
valid = false;
}
@@ -281,16 +295,13 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
}
/* create new stroke */
- new_stroke = MEM_dupallocN(gps_from);
- new_stroke->points = MEM_dupallocN(gps_from->points);
- new_stroke->triangles = MEM_dupallocN(gps_from->triangles);
- new_stroke->tot_triangles = 0;
- new_stroke->flag |= GP_STROKE_RECALC_CACHES;
+ new_stroke = BKE_gpencil_stroke_duplicate(gps_from);
if (valid) {
/* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */
if (gps_from->totpoints > gps_to->totpoints) {
new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points) * gps_to->totpoints);
+ new_stroke->dvert = MEM_recallocN(new_stroke->dvert, sizeof(*new_stroke->dvert) * gps_to->totpoints);
new_stroke->totpoints = gps_to->totpoints;
new_stroke->tot_triangles = 0;
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
@@ -302,6 +313,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
/* need an empty stroke to keep index correct for lookup, but resize to smallest size */
new_stroke->totpoints = 0;
new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points));
+ new_stroke->dvert = MEM_recallocN(new_stroke->dvert, sizeof(*new_stroke->dvert));
new_stroke->tot_triangles = 0;
new_stroke->triangles = MEM_recallocN(new_stroke->triangles, sizeof(*new_stroke->triangles));
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
@@ -317,17 +329,17 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
/* Drawing Callbacks */
/* Drawing callback for modal operator in screen mode */
-static void gpencil_interpolate_draw_screen(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
+static void gpencil_interpolate_draw_screen(const struct bContext *C, ARegion *UNUSED(ar), void *arg)
{
tGPDinterpolate *tgpi = (tGPDinterpolate *)arg;
- ED_gp_draw_interpolation(tgpi, REGION_DRAW_POST_PIXEL);
+ ED_gp_draw_interpolation(C, tgpi, REGION_DRAW_POST_PIXEL);
}
/* Drawing callback for modal operator in 3d mode */
-static void gpencil_interpolate_draw_3d(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
+static void gpencil_interpolate_draw_3d(const bContext *C, ARegion *UNUSED(ar), void *arg)
{
tGPDinterpolate *tgpi = (tGPDinterpolate *)arg;
- ED_gp_draw_interpolation(tgpi, REGION_DRAW_POST_VIEW);
+ ED_gp_draw_interpolation(C, tgpi, REGION_DRAW_POST_VIEW);
}
/* ----------------------- */
@@ -392,6 +404,7 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op)
{
tGPDinterpolate *tgpi = op->customdata;
tGPDinterpolate_layer *tgpil;
+ bGPdata *gpd = tgpi->gpd;
/* don't assume that operator data exists at all */
if (tgpi) {
@@ -416,6 +429,7 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op)
BLI_freelistN(&tgpi->ilayers);
MEM_freeN(tgpi);
}
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
/* clear pointer */
@@ -483,9 +497,10 @@ static int gpencil_interpolate_init(bContext *C, wmOperator *op)
static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
wmWindow *win = CTX_wm_window(C);
- Scene *scene = CTX_data_scene(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
bGPDframe *actframe = gpl->actframe;
tGPDinterpolate *tgpi = NULL;
@@ -496,7 +511,7 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent
}
/* cannot interpolate in extremes */
- if (ELEM(CFRA, actframe->framenum, actframe->next->framenum)) {
+ if (ELEM(cfra_eval, actframe->framenum, actframe->next->framenum)) {
BKE_report(op->reports, RPT_ERROR, "Cannot interpolate as current frame already has existing grease pencil frames");
return OPERATOR_CANCELLED;
}
@@ -529,6 +544,7 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent
/* update shift indicator in header */
gpencil_interpolate_status_indicators(C, tgpi);
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
/* add a modal handler for this operator */
@@ -571,6 +587,8 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent
/* make copy of source stroke, then adjust pointer to points too */
gps_dst = MEM_dupallocN(gps_src);
gps_dst->points = MEM_dupallocN(gps_src->points);
+ gps_dst->dvert = MEM_dupallocN(gps_src->dvert);
+ BKE_gpencil_stroke_weights_duplicate(gps_src, gps_dst);
gps_dst->triangles = MEM_dupallocN(gps_src->triangles);
gps_dst->flag |= GP_STROKE_RECALC_CACHES;
BLI_addtail(&gpf_dst->strokes, gps_dst);
@@ -902,8 +920,11 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C);
bGPDframe *actframe = active_gpl->actframe;
- Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
ToolSettings *ts = CTX_data_tool_settings(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
GP_Interpolate_Settings *ipo_settings = &ts->gp_interpolate;
eGP_Interpolate_SettingsFlag flag = ipo_settings->flag;
@@ -913,7 +934,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* cannot interpolate in extremes */
- if (ELEM(CFRA, actframe->framenum, actframe->next->framenum)) {
+ if (ELEM(cfra_eval, actframe->framenum, actframe->next->framenum)) {
BKE_report(op->reports, RPT_ERROR, "Cannot interpolate as current frame already has existing grease pencil frames");
return OPERATOR_CANCELLED;
}
@@ -961,7 +982,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
/* create new strokes data with interpolated points reading original stroke */
for (gps_from = prevFrame->strokes.first; gps_from; gps_from = gps_from->next) {
- bGPDstroke *new_stroke;
+ bGPDstroke *new_stroke = NULL;
/* only selected */
if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) {
@@ -972,7 +993,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
continue;
}
@@ -990,15 +1011,15 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
}
/* create new stroke */
- new_stroke = MEM_dupallocN(gps_from);
- new_stroke->points = MEM_dupallocN(gps_from->points);
- new_stroke->triangles = MEM_dupallocN(gps_from->triangles);
- new_stroke->tot_triangles = 0;
- new_stroke->flag |= GP_STROKE_RECALC_CACHES;
+ new_stroke = BKE_gpencil_stroke_duplicate(gps_from);
/* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */
if (gps_from->totpoints > gps_to->totpoints) {
+ /* free weights of removed points */
+ BKE_defvert_array_free_elems(gps_from->dvert + gps_to->totpoints, gps_from->totpoints - gps_to->totpoints);
+
new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points) * gps_to->totpoints);
+ new_stroke->dvert = MEM_recallocN(new_stroke->dvert, sizeof(*new_stroke->dvert) * gps_to->totpoints);
new_stroke->totpoints = gps_to->totpoints;
new_stroke->tot_triangles = 0;
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
@@ -1014,6 +1035,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
}
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -1055,6 +1077,8 @@ static bool gpencil_interpolate_reverse_poll(bContext *C)
static int gpencil_interpolate_reverse_exec(bContext *C, wmOperator *UNUSED(op))
{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+
/* Go through each layer, deleting the breakdowns around the current frame,
* but only if there is a keyframe nearby to stop at
*/
@@ -1123,6 +1147,7 @@ static int gpencil_interpolate_reverse_exec(bContext *C, wmOperator *UNUSED(op))
CTX_DATA_END;
/* notifiers */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/gpencil/gpencil_old.c b/source/blender/editors/gpencil/gpencil_old.c
new file mode 100644
index 00000000000..76d519fe371
--- /dev/null
+++ b/source/blender/editors/gpencil/gpencil_old.c
@@ -0,0 +1,219 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2018, Blender Foundation,
+ * This is a new part of Blender
+ *
+ * Contributor(s): Antonio Vazquez
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Use deprecated data to convert old 2.7x files
+ */
+
+/** \file blender/editors/gpencil/gpencil_old.c
+ * \ingroup edgpencil
+ */
+
+ /* allow to use deprecated functionality */
+#define DNA_DEPRECATED_ALLOW
+
+#include <stdio.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_main.h"
+#include "BKE_brush.h"
+#include "BKE_context.h"
+#include "BKE_deform.h"
+#include "BKE_gpencil.h"
+#include "BKE_object.h"
+#include "BKE_material.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_object.h"
+#include "ED_gpencil.h"
+
+#include "gpencil_intern.h"
+
+ /* Free all of a gp-colors */
+static void free_gpencil_colors(bGPDpalette *palette)
+{
+ /* error checking */
+ if (palette == NULL) {
+ return;
+ }
+
+ /* free colors */
+ BLI_freelistN(&palette->colors);
+}
+
+/* Free all of the gp-palettes and colors */
+static void free_palettes(ListBase *list)
+{
+ bGPDpalette *palette_next;
+
+ /* error checking */
+ if (list == NULL) {
+ return;
+ }
+
+ /* delete palettes */
+ for (bGPDpalette *palette = list->first; palette; palette = palette_next) {
+ palette_next = palette->next;
+ /* free palette colors */
+ free_gpencil_colors(palette);
+
+ MEM_freeN(palette);
+ }
+ BLI_listbase_clear(list);
+}
+
+/* ***************** Convert old 2.7 files to 2.8 ************************ */
+static bool gpencil_convert_old_files_poll(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+
+ return (int) (scene->gpd != NULL);
+}
+
+static int gpencil_convert_old_files_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ /* Convert grease pencil scene datablock to GP object */
+ if ((scene->gpd) && (view_layer != NULL)) {
+ Object *ob;
+ ob = BKE_object_add_for_data(bmain, view_layer, OB_GPENCIL, "GP_Scene", &scene->gpd->id, false);
+ zero_v3(ob->loc);
+
+ Paint *paint = BKE_brush_get_gpencil_paint(ts);
+ /* if not exist, create a new one */
+ if (paint->brush == NULL) {
+ /* create new brushes */
+ BKE_brush_gpencil_presets(C);
+ }
+
+ /* convert grease pencil palettes (version >= 2.78) to materials and weights */
+ bGPdata *gpd = scene->gpd;
+ for (const bGPDpalette *palette = gpd->palettes.first; palette; palette = palette->next) {
+ for (bGPDpalettecolor *palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
+
+ /* create material slot */
+ BKE_object_material_slot_add(bmain, ob);
+ Material *ma = BKE_material_add_gpencil(bmain, palcolor->info);
+ assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
+
+ /* copy color settings */
+ MaterialGPencilStyle *gp_style = ma->gp_style;
+ copy_v4_v4(gp_style->stroke_rgba, palcolor->color);
+ copy_v4_v4(gp_style->fill_rgba, palcolor->fill);
+ gp_style->flag = palcolor->flag;
+
+ /* fix strokes */
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ if ((gps->colorname[0] != '\0') &&
+ (STREQ(gps->colorname, palcolor->info)))
+ {
+ gps->mat_nr = ob->totcol - 1;
+ gps->colorname[0] = '\0';
+ /* create weights array */
+ gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* free palettes */
+ free_palettes(&gpd->palettes);
+
+ /* disable all GP modes */
+ ED_gpencil_setup_modes(C, gpd, 0);
+
+ /* set cache as dirty */
+ BKE_gpencil_batch_cache_dirty(ob->data);
+
+ scene->gpd = NULL;
+ }
+
+#if 0 /* GPXX */
+ /* Handle object-linked grease pencil datablocks */
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->gpd) {
+ if (ob->type == OB_GPENCIL) {
+ /* GP Object - remap the links */
+ ob->data = ob->gpd;
+ ob->gpd = NULL;
+ }
+ else if (ob->type == OB_EMPTY) {
+ /* Empty with GP data - This should be able to be converted
+ * to a GP object with little data loss
+ */
+ ob->data = ob->gpd;
+ ob->gpd = NULL;
+ ob->type = OB_GPENCIL;
+ }
+ else {
+ /* FIXME: What to do in this case?
+ *
+ * We cannot create new objects for these, as we don't have a scene & scene layer
+ * to put them into from here...
+ */
+ printf("WARNING: Old Grease Pencil data ('%s') still exists on Object '%s'\n",
+ ob->gpd->id.name + 2, ob->id.name + 2);
+ }
+ }
+ }
+#endif
+
+ /* notifiers */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_convert_old_files(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Convert 2.7 Grease Pencil File";
+ ot->idname = "GPENCIL_OT_convert_old_files";
+ ot->description = "Convert 2.7x grease pencil files to 2.8";
+
+ /* callbacks */
+ ot->exec = gpencil_convert_old_files_exec;
+ ot->poll = gpencil_convert_old_files_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 3f114a4dd4a..b2e1758b169 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -35,8 +35,14 @@
#include "BLI_sys_types.h"
#include "BKE_context.h"
+#include "BKE_brush.h"
+#include "BKE_gpencil.h"
+#include "DNA_brush_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -52,7 +58,7 @@
/* ****************************************** */
/* Grease Pencil Keymaps */
-/* Generic Drawing Keymap */
+/* Generic Drawing Keymap - Annotations */
static void ed_keymap_gpencil_general(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil", 0, 0);
@@ -60,36 +66,22 @@ static void ed_keymap_gpencil_general(wmKeyConfig *keyconf)
/* Draw --------------------------------------- */
/* draw */
- kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, DKEY);
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_annotate", LEFTMOUSE, KM_PRESS, 0, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
/* draw - straight lines */
- kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, DKEY);
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_annotate", LEFTMOUSE, KM_PRESS, KM_ALT, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_STRAIGHT);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
/* draw - poly lines */
- kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, KM_CTRL, DKEY);
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_annotate", LEFTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_POLY);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
/* erase */
- kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, 0, DKEY);
- RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER);
- RNA_boolean_set(kmi->ptr, "wait_for_input", false);
-
- /* Tablet Mappings for Drawing ------------------ */
- /* For now, only support direct drawing using the eraser, as most users using a tablet
- * may still want to use that as their primary pointing device!
- */
-#if 0
- kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", TABLET_STYLUS, KM_PRESS, 0, 0);
- RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW);
- RNA_boolean_set(kmi->ptr, "wait_for_input", false);
-#endif
-
- kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", TABLET_ERASER, KM_PRESS, 0, 0);
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_annotate", RIGHTMOUSE, KM_PRESS, 0, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
@@ -121,67 +113,85 @@ static bool gp_stroke_editmode_poll(bContext *C)
return (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE));
}
-/* Stroke Editing Keymap - Only when editmode is enabled */
-static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
+/* Poll callback for stroke painting mode */
+static bool gp_stroke_paintmode_poll(bContext *C)
{
- wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Edit Mode", 0, 0);
- wmKeyMapItem *kmi;
-
- /* set poll callback - so that this keymap only gets enabled when stroke editmode is enabled */
- keymap->poll = gp_stroke_editmode_poll;
-
- /* ----------------------------------------------- */
-
- /* Exit EditMode */
- WM_keymap_add_item(keymap, "GPENCIL_OT_editmode_toggle", TABKEY, KM_PRESS, 0, 0);
-
- /* Pie Menu - For settings/tools easy access */
- WM_keymap_add_menu_pie(keymap, "GPENCIL_MT_pie_sculpt", EKEY, KM_PRESS, 0, DKEY);
-
- /* Brush Settings */
- /* NOTE: We cannot expose these in the standard keymap, as they will interfere with regular hotkeys
- * in other modes. However, when we are dealing with Stroke Edit Mode, we know for certain
- * that the only data being edited is that of the Grease Pencil strokes
- */
-
- /* CTRL + FKEY = Eraser Radius */
- kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0);
- RNA_string_set(kmi->ptr, "data_path_primary", "user_preferences.edit.grease_pencil_eraser_radius");
-
- /* Interpolation */
- WM_keymap_add_item(keymap, "GPENCIL_OT_interpolate", EKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
- WM_keymap_add_item(keymap, "GPENCIL_OT_interpolate_sequence", EKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
+ /* TODO: limit this to mode, but review 2D editors */
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE));
+}
- /* Sculpting ------------------------------------- */
+/* Poll callback for stroke painting (draw brush) */
+static bool gp_stroke_paintmode_draw_poll(bContext *C)
+{
+ /* TODO: limit this to mode, but review 2D editors */
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Brush *brush = BKE_brush_getactive_gpencil(ts);
+ return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) &&
+ (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_DRAW));
+}
- /* Brush-Based Editing:
- * EKEY + LMB = Single stroke, draw immediately
- * + Other Modifiers (Ctrl/Shift) = Invert, Smooth, etc.
- *
- * For the modal version, use D+E -> Sculpt
- */
- kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, 0, EKEY);
- RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+/* Poll callback for stroke painting (erase brush) */
+static bool gp_stroke_paintmode_erase_poll(bContext *C)
+{
+ /* TODO: limit this to mode, but review 2D editors */
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Brush *brush = BKE_brush_getactive_gpencil(ts);
+ return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) &&
+ (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE));
+}
- kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_CTRL, EKEY);
- RNA_boolean_set(kmi->ptr, "wait_for_input", false);
- /*RNA_boolean_set(kmi->ptr, "use_invert", true);*/
+/* Poll callback for stroke painting (fill) */
+static bool gp_stroke_paintmode_fill_poll(bContext *C)
+{
+ /* TODO: limit this to mode, but review 2D editors */
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Brush *brush = BKE_brush_getactive_gpencil(ts);
+ return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) &&
+ (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_FILL));
+}
- kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_SHIFT, EKEY);
- RNA_boolean_set(kmi->ptr, "wait_for_input", false);
- /*RNA_boolean_set(kmi->ptr, "use_smooth", true);*/
+/* Poll callback for stroke sculpting mode */
+static bool gp_stroke_sculptmode_poll(bContext *C)
+{
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ Object *ob = CTX_data_active_object(C);
+ ScrArea *sa = CTX_wm_area(C);
+
+ /* if not gpencil object and not view3d, need sculpt keys if edit mode */
+ if (sa->spacetype != SPACE_VIEW3D) {
+ return ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
+ }
+ else {
+ /* weight paint is a submode of sculpt */
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ return GPENCIL_SCULPT_OR_WEIGHT_MODE(gpd);
+ }
+ }
+
+ return 0;
+}
+/* Poll callback for stroke weight paint mode */
+static bool gp_stroke_weightmode_poll(bContext *C)
+{
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ Object *ob = CTX_data_active_object(C);
- /* Shift-FKEY = Sculpt Strength */
- kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.strength");
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ return (gpd && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE));
+ }
- /* FKEY = Sculpt Brush Size */
- kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0);
- RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.size");
+ return 0;
+}
+static void ed_keymap_gpencil_selection(wmKeyMap *keymap)
+{
+ wmKeyMapItem *kmi;
- /* Selection ------------------------------------- */
/* select all */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_all", AKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "action", SEL_SELECT);
@@ -204,17 +214,14 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "deselect", true);
/* In the Node Editor, lasso select needs ALT modifier too (as somehow CTRL+LMB drag gets taken for "cut" quite early)
- * There probably isn't too much harm adding this for other editors too as part of standard GP editing keymap. This hotkey
- * combo doesn't seem to see much use under standard scenarios?
- */
+ * There probably isn't too much harm adding this for other editors too as part of standard GP editing keymap. This hotkey
+ * combo doesn't seem to see much use under standard scenarios?
+ */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT | KM_CTRL | KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "deselect", true);
- /* normal select */
- WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
-
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", true);
RNA_boolean_set(kmi->ptr, "toggle", true);
@@ -223,17 +230,130 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "entire_strokes", true);
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "entire_strokes", true);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+
/* select linked */
/* NOTE: While LKEY is redundant, not having it breaks the mode illusion too much */
WM_keymap_add_item(keymap, "GPENCIL_OT_select_linked", LKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "GPENCIL_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
+ /* select alternate */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_select_alternate", LKEY, KM_PRESS, KM_SHIFT, 0);
+
/* select grouped */
WM_keymap_add_item(keymap, "GPENCIL_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
/* select more/less */
WM_keymap_add_item(keymap, "GPENCIL_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "GPENCIL_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
+}
+
+static void ed_keymap_gpencil_display(wmKeyMap *keymap)
+{
+ wmKeyMapItem *kmi;
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_edit_lines");
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0);
+ RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_multiedit_line_only");
+}
+
+static void ed_keymap_gpencil_sculpt(wmKeyMap *keymap)
+{
+ wmKeyMapItem *kmi;
+
+ /* Pie Menu - For settings/tools easy access */
+ WM_keymap_add_menu_pie(keymap, "GPENCIL_PIE_sculpt", EKEY, KM_PRESS, 0, DKEY);
+
+ /* Sculpting ------------------------------------- */
+
+ /* Brush-Based Editing:
+ * EKEY + LMB = Single stroke, draw immediately
+ * + Other Modifiers (Ctrl/Shift) = Invert, Smooth, etc.
+ *
+ * For the modal version, use D+E -> Sculpt
+ */
+ /* GPXX: disabled to make toolsystem works */
+ //kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, 0, 0);
+ //RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+ RNA_boolean_set(kmi->ptr, "keep_brush", true);
+ /*RNA_boolean_set(kmi->ptr, "use_invert", true);*/
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+ RNA_boolean_set(kmi->ptr, "keep_brush", true);
+ /*RNA_boolean_set(kmi->ptr, "use_smooth", true);*/
+
+ /* Shift-FKEY = Sculpt Strength */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.strength");
+
+ /* FKEY = Sculpt Brush Size */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.size");
+
+ /* menu sculpt specials */
+ WM_keymap_add_menu(keymap, "VIEW3D_MT_gpencil_sculpt_specials", WKEY, KM_PRESS, 0, 0);
+}
+
+static void ed_keymap_gpencil_weight(wmKeyMap *keymap)
+{
+ wmKeyMapItem *kmi;
+
+
+ /* Brush-Based Editing:
+ * EKEY + LMB = Single stroke, draw immediately
+ * + Other Modifiers (Ctrl/Shift) = Invert, Smooth, etc.
+ *
+ * For the modal version, use D+E -> Sculpt
+ */
+ /* GPXX: disabled to make toolsystem works */
+ //kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, 0, 0);
+ //RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+ RNA_boolean_set(kmi->ptr, "keep_brush", true);
+ /*RNA_boolean_set(kmi->ptr, "use_invert", true);*/
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+ RNA_boolean_set(kmi->ptr, "keep_brush", true);
+ /*RNA_boolean_set(kmi->ptr, "use_smooth", true);*/
+}
+
+/* Stroke Editing Keymap - Only when editmode is enabled */
+static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
+{
+ wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Edit Mode", 0, 0);
+ wmKeyMapItem *kmi;
+
+ /* set poll callback - so that this keymap only gets enabled when stroke editmode is enabled */
+ keymap->poll = gp_stroke_editmode_poll;
+
+ /* ----------------------------------------------- */
+
+ /* Brush Settings */
+ /* NOTE: We cannot expose these in the standard keymap, as they will interfere with regular hotkeys
+ * in other modes. However, when we are dealing with Stroke Edit Mode, we know for certain
+ * that the only data being edited is that of the Grease Pencil strokes
+ */
+
+ /* Interpolation */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_interpolate", EKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
+ WM_keymap_add_item(keymap, "GPENCIL_OT_interpolate_sequence", EKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
+
+ /* normal select */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
+
+ /* Selection */
+ ed_keymap_gpencil_selection(keymap);
/* Editing ----------------------------------------- */
@@ -251,7 +371,13 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "GPENCIL_OT_active_frames_delete_all", DELKEY, KM_PRESS, KM_SHIFT, 0);
/* menu edit specials */
- WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_edit_specials", WKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_menu(keymap, "VIEW3D_MT_gpencil_edit_specials", WKEY, KM_PRESS, 0, 0);
+
+ /* menu separate */
+ WM_keymap_add_menu(keymap, "GPENCIL_MT_separate", PKEY, KM_PRESS, 0, 0);
+
+ /* split strokes */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_stroke_split", VKEY, KM_PRESS, 0, 0);
/* join strokes */
WM_keymap_add_item(keymap, "GPENCIL_OT_stroke_join", JKEY, KM_PRESS, KM_CTRL, 0);
@@ -271,7 +397,6 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
/* snap */
WM_keymap_add_menu(keymap, "GPENCIL_MT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
-
/* convert to geometry */
WM_keymap_add_item(keymap, "GPENCIL_OT_convert", CKEY, KM_PRESS, KM_ALT, 0);
@@ -288,6 +413,9 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "GPENCIL_OT_selection_opacity_toggle", HKEY, KM_PRESS, KM_CTRL, 0);
+ /* Display. */
+ ed_keymap_gpencil_display(keymap);
+
/* Isolate Layer */
WM_keymap_add_item(keymap, "GPENCIL_OT_layer_isolate", PADASTERKEY, KM_PRESS, 0, 0);
@@ -317,27 +445,233 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
/* Proportional Editing */
ED_keymap_proportional_cycle(keyconf, keymap);
ED_keymap_proportional_editmode(keyconf, keymap, true);
+
+ /* menu - add GP object (3d view only) */
+ WM_keymap_add_item(keymap, "OBJECT_OT_gpencil_add", AKEY, KM_PRESS, KM_SHIFT, 0);
+
+ /* menu vertex group */
+ WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_vertex_group", GKEY, KM_PRESS, KM_CTRL, 0);
+
+ /* toggle edit mode */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_editmode_toggle", TABKEY, KM_PRESS, 0, 0);
+}
+
+/* keys for draw with a drawing brush (no fill) */
+static void ed_keymap_gpencil_painting_draw(wmKeyConfig *keyconf)
+{
+ wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Paint (Draw brush)", 0, 0);
+ wmKeyMapItem *kmi;
+
+ /* set poll callback */
+ keymap->poll = gp_stroke_paintmode_draw_poll;
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
+ /* draw - straight lines */
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_ALT, 0);
+ RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_STRAIGHT);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
+ /* draw - poly lines */
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0);
+ RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_POLY);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
+ /* erase */
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
+ RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
+ /* Tablet Mappings for Drawing ------------------ */
+ /* For now, only support direct drawing using the eraser, as most users using a tablet
+ * may still want to use that as their primary pointing device!
+ */
+#if 0
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", TABLET_STYLUS, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+#endif
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", TABLET_ERASER, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
+ /* Selection (used by eraser) */
+ /* border select */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_select_border", BKEY, KM_PRESS, 0, 0);
+
+ /* lasso select */
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+}
+
+/* keys for draw with a eraser brush (erase) */
+static void ed_keymap_gpencil_painting_erase(wmKeyConfig *keyconf)
+{
+ wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Paint (Erase)", 0, 0);
+ wmKeyMapItem *kmi;
+
+ /* set poll callback */
+ keymap->poll = gp_stroke_paintmode_erase_poll;
+
+ /* erase */
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", TABLET_ERASER, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
+ /* Selection (used by eraser) */
+ /* border select */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_select_border", BKEY, KM_PRESS, 0, 0);
+
+ /* lasso select */
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+}
+
+/* keys for draw with a fill brush */
+static void ed_keymap_gpencil_painting_fill(wmKeyConfig *keyconf)
+{
+ wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Paint (Fill)", 0, 0);
+ wmKeyMapItem *kmi;
+
+ /* set poll callback */
+ keymap->poll = gp_stroke_paintmode_fill_poll;
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_fill", LEFTMOUSE, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "on_back", false);
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_fill", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "on_back", true);
+
+ /* if press alternative key, the brush now it's for drawing areas */
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
+ RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+ /* disable straight lines */
+ RNA_boolean_set(kmi->ptr, "disable_straight", true);
+
+ /* if press alternative key, the brush now it's for drawing lines */
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_ALT, 0);
+ RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+ /* disable straight lines */
+ RNA_boolean_set(kmi->ptr, "disable_straight", true);
+ /* enable special stroke with no fill flag */
+ RNA_boolean_set(kmi->ptr, "disable_fill", true);
+}
+
+/* Stroke Painting Keymap - Only when paintmode is enabled */
+static void ed_keymap_gpencil_painting(wmKeyConfig *keyconf)
+{
+ wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Paint Mode", 0, 0);
+ wmKeyMapItem *kmi;
+
+ /* set poll callback - so that this keymap only gets enabled when stroke paintmode is enabled */
+ keymap->poll = gp_stroke_paintmode_poll;
+
+ /* FKEY = Brush Size */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_paint.brush.size");
+
+ /* CTRL + FKEY = Eraser Radius */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "data_path_primary", "user_preferences.edit.grease_pencil_eraser_radius");
+
+ /* menu draw specials */
+ WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_draw_specials", WKEY, KM_PRESS, 0, 0);
+
+ /* menu draw delete */
+ WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_draw_delete", XKEY, KM_PRESS, 0, 0);
+
}
+/* Stroke Sculpting Keymap - Only when sculptmode is enabled */
+static void ed_keymap_gpencil_sculpting(wmKeyConfig *keyconf)
+{
+ wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Sculpt Mode", 0, 0);
+
+ /* set poll callback - so that this keymap only gets enabled when stroke sculptmode is enabled */
+ keymap->poll = gp_stroke_sculptmode_poll;
+
+ /* Selection */
+ ed_keymap_gpencil_selection(keymap);
+
+ /* sculpt */
+ ed_keymap_gpencil_sculpt(keymap);
+
+ /* Display. */
+ ed_keymap_gpencil_display(keymap);
+}
+
+/* Stroke Weight Paint Keymap - Only when weight is enabled */
+static void ed_keymap_gpencil_weightpainting(wmKeyConfig *keyconf)
+{
+ wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Weight Mode", 0, 0);
+ wmKeyMapItem *kmi;
+
+ /* set poll callback - so that this keymap only gets enabled when stroke sculptmode is enabled */
+ keymap->poll = gp_stroke_weightmode_poll;
+
+ /* Selection */
+ ed_keymap_gpencil_selection(keymap);
+
+ /* sculpt */
+ ed_keymap_gpencil_weight(keymap);
+
+ /* Shift-FKEY = Sculpt Strength */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.weight_brush.strength");
+
+ /* FKEY = Sculpt Brush Size */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.weight_brush.size");
+
+ /* Display. */
+ ed_keymap_gpencil_display(keymap);
+}
/* ==================== */
void ED_keymap_gpencil(wmKeyConfig *keyconf)
{
ed_keymap_gpencil_general(keyconf);
ed_keymap_gpencil_editing(keyconf);
+ ed_keymap_gpencil_painting(keyconf);
+ ed_keymap_gpencil_painting_draw(keyconf);
+ ed_keymap_gpencil_painting_erase(keyconf);
+ ed_keymap_gpencil_painting_fill(keyconf);
+ ed_keymap_gpencil_sculpting(keyconf);
+ ed_keymap_gpencil_weightpainting(keyconf);
}
/* ****************************************** */
void ED_operatortypes_gpencil(void)
{
+ /* Annotations -------------------- */
+
+ WM_operatortype_append(GPENCIL_OT_annotate);
+
/* Drawing ----------------------- */
WM_operatortype_append(GPENCIL_OT_draw);
+ WM_operatortype_append(GPENCIL_OT_fill);
/* Editing (Strokes) ------------ */
WM_operatortype_append(GPENCIL_OT_editmode_toggle);
+ WM_operatortype_append(GPENCIL_OT_paintmode_toggle);
+ WM_operatortype_append(GPENCIL_OT_sculptmode_toggle);
+ WM_operatortype_append(GPENCIL_OT_weightmode_toggle);
WM_operatortype_append(GPENCIL_OT_selection_opacity_toggle);
WM_operatortype_append(GPENCIL_OT_select);
@@ -352,6 +686,7 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_select_less);
WM_operatortype_append(GPENCIL_OT_select_first);
WM_operatortype_append(GPENCIL_OT_select_last);
+ WM_operatortype_append(GPENCIL_OT_select_alternate);
WM_operatortype_append(GPENCIL_OT_duplicate);
WM_operatortype_append(GPENCIL_OT_delete);
@@ -391,6 +726,8 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_active_frame_delete);
WM_operatortype_append(GPENCIL_OT_active_frames_delete_all);
+ WM_operatortype_append(GPENCIL_OT_frame_duplicate);
+ WM_operatortype_append(GPENCIL_OT_frame_clean_fill);
WM_operatortype_append(GPENCIL_OT_convert);
@@ -402,36 +739,46 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_stroke_join);
WM_operatortype_append(GPENCIL_OT_stroke_flip);
WM_operatortype_append(GPENCIL_OT_stroke_subdivide);
+ WM_operatortype_append(GPENCIL_OT_stroke_simplify);
+ WM_operatortype_append(GPENCIL_OT_stroke_simplify_fixed);
+ WM_operatortype_append(GPENCIL_OT_stroke_separate);
+ WM_operatortype_append(GPENCIL_OT_stroke_split);
- WM_operatortype_append(GPENCIL_OT_palette_add);
- WM_operatortype_append(GPENCIL_OT_palette_remove);
- WM_operatortype_append(GPENCIL_OT_palette_change);
- WM_operatortype_append(GPENCIL_OT_palette_lock_layer);
- WM_operatortype_append(GPENCIL_OT_palettecolor_add);
- WM_operatortype_append(GPENCIL_OT_palettecolor_remove);
- WM_operatortype_append(GPENCIL_OT_palettecolor_isolate);
- WM_operatortype_append(GPENCIL_OT_palettecolor_hide);
- WM_operatortype_append(GPENCIL_OT_palettecolor_reveal);
- WM_operatortype_append(GPENCIL_OT_palettecolor_lock_all);
- WM_operatortype_append(GPENCIL_OT_palettecolor_unlock_all);
- WM_operatortype_append(GPENCIL_OT_palettecolor_move);
- WM_operatortype_append(GPENCIL_OT_palettecolor_select);
- WM_operatortype_append(GPENCIL_OT_palettecolor_copy);
-
- WM_operatortype_append(GPENCIL_OT_brush_add);
- WM_operatortype_append(GPENCIL_OT_brush_remove);
- WM_operatortype_append(GPENCIL_OT_brush_change);
- WM_operatortype_append(GPENCIL_OT_brush_move);
WM_operatortype_append(GPENCIL_OT_brush_presets_create);
- WM_operatortype_append(GPENCIL_OT_brush_copy);
WM_operatortype_append(GPENCIL_OT_brush_select);
+ WM_operatortype_append(GPENCIL_OT_sculpt_select);
+
+ /* vertex groups */
+ WM_operatortype_append(GPENCIL_OT_vertex_group_assign);
+ WM_operatortype_append(GPENCIL_OT_vertex_group_remove_from);
+ WM_operatortype_append(GPENCIL_OT_vertex_group_select);
+ WM_operatortype_append(GPENCIL_OT_vertex_group_deselect);
+ WM_operatortype_append(GPENCIL_OT_vertex_group_invert);
+ WM_operatortype_append(GPENCIL_OT_vertex_group_smooth);
+
+ /* color handle */
+ WM_operatortype_append(GPENCIL_OT_lock_layer);
+ WM_operatortype_append(GPENCIL_OT_color_isolate);
+ WM_operatortype_append(GPENCIL_OT_color_hide);
+ WM_operatortype_append(GPENCIL_OT_color_reveal);
+ WM_operatortype_append(GPENCIL_OT_color_lock_all);
+ WM_operatortype_append(GPENCIL_OT_color_unlock_all);
+ WM_operatortype_append(GPENCIL_OT_color_select);
+
/* Editing (Time) --------------- */
/* Interpolation */
WM_operatortype_append(GPENCIL_OT_interpolate);
WM_operatortype_append(GPENCIL_OT_interpolate_sequence);
WM_operatortype_append(GPENCIL_OT_interpolate_reverse);
+
+ /* Primitives */
+ WM_operatortype_append(GPENCIL_OT_primitive);
+
+ /* convert old 2.7 files to 2.8 */
+ WM_operatortype_append(GPENCIL_OT_convert_old_files);
+
}
void ED_operatormacros_gpencil(void)
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index ec8a213301f..d4371926eb4 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -46,26 +46,32 @@
#include "PIL_time.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_material_types.h"
+#include "DNA_brush_types.h"
+#include "DNA_windowmanager_types.h"
+
#include "BKE_colortools.h"
+#include "BKE_main.h"
+#include "BKE_brush.h"
+#include "BKE_paint.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
-#include "BKE_main.h"
-#include "BKE_paint.h"
#include "BKE_report.h"
+#include "BKE_layer.h"
+#include "BKE_material.h"
#include "BKE_screen.h"
#include "BKE_tracking.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_gpencil_types.h"
-#include "DNA_brush_types.h"
-#include "DNA_windowmanager_types.h"
-
#include "UI_view2d.h"
#include "ED_gpencil.h"
#include "ED_screen.h"
+#include "ED_object.h"
#include "ED_view3d.h"
#include "ED_clip.h"
@@ -82,6 +88,7 @@
#include "WM_types.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "gpencil_intern.h"
@@ -110,6 +117,8 @@ typedef enum eGPencil_PaintFlags {
GP_PAINTFLAG_STROKEADDED = (1 << 1),
GP_PAINTFLAG_V3D_ERASER_DEPTH = (1 << 2),
GP_PAINTFLAG_SELECTMASK = (1 << 3),
+ GP_PAINTFLAG_HARD_ERASER = (1 << 4),
+ GP_PAINTFLAG_STROKE_ERASER = (1 << 5),
} eGPencil_PaintFlags;
@@ -117,10 +126,13 @@ typedef enum eGPencil_PaintFlags {
* "p" = op->customdata
*/
typedef struct tGPsdata {
- Main *bmain;
+ bContext *C;
+
+ Main *bmain; /* main database pointer */
Scene *scene; /* current scene from context */
struct Depsgraph *depsgraph;
+ Object *ob; /* current object */
wmWindow *win; /* window where painting originated */
ScrArea *sa; /* area where painting originated */
ARegion *ar; /* region where painting originated */
@@ -165,14 +177,23 @@ typedef struct tGPsdata {
void *erasercursor; /* radial cursor data for drawing eraser */
- bGPDpalettecolor *palettecolor; /* current palette color */
- bGPDbrush *brush; /* current drawing brush */
+ /* mat settings are only used for 3D view */
+ Material *material; /* current material */
+
+ Brush *brush; /* current drawing brush */
+ Brush *eraser; /* default eraser brush */
short straight[2]; /* 1: line horizontal, 2: line vertical, other: not defined, second element position */
int lock_axis; /* lock drawing to one axis */
+ bool disable_fill; /* the stroke is no fill mode */
RNG *rng;
short keymodifier; /* key used for invoking the operator */
+ short shift; /* shift modifier flag */
+
+ float totpixlen; /* size in pixels for uv calculation */
+
+ ReportList *reports;
} tGPsdata;
/* ------ */
@@ -183,6 +204,14 @@ 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)
+{
+ if (gpd) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+ }
+}
+
static bool gp_stroke_added_check(tGPsdata *p)
{
return (p->gpf && p->gpf->strokes.last && p->flags & GP_PAINTFLAG_STROKEADDED);
@@ -192,6 +221,9 @@ static void gp_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);
}
/* ------ */
@@ -206,30 +238,42 @@ static void gp_session_validatebuffer(tGPsdata *p);
static bool gpencil_draw_poll(bContext *C)
{
if (ED_operator_regionactive(C)) {
- /* check if current context can support GPencil data */
- if (ED_gpencil_data_get_pointers(C, NULL) != NULL) {
- /* check if Grease Pencil isn't already running */
- if (ED_gpencil_session_active() == 0)
- return 1;
- else
- CTX_wm_operator_poll_msg_set(C, "Grease Pencil operator is already active");
+ ScrArea *sa = CTX_wm_area(C);
+ if (!ELEM(sa->spacetype, SPACE_VIEW3D)) {
+ /* check if current context can support GPencil data */
+ if (ED_gpencil_data_get_pointers(C, NULL) != NULL) {
+ /* check if Grease Pencil isn't already running */
+ if (ED_gpencil_session_active() == 0)
+ return 1;
+ else
+ CTX_wm_operator_poll_msg_set(C, "Grease Pencil operator is already active");
+ }
+ else {
+ CTX_wm_operator_poll_msg_set(C, "Failed to find Grease Pencil data to draw into");
+ }
+ return 0;
}
+ /* 3D Viewport */
else {
- CTX_wm_operator_poll_msg_set(C, "Failed to find Grease Pencil data to draw into");
+ if (ED_gpencil_session_active() == 0) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
}
}
else {
CTX_wm_operator_poll_msg_set(C, "Active region not set");
+ return 0;
}
-
- return 0;
}
/* check if projecting strokes into 3d-geometry in the 3D-View */
static bool gpencil_project_check(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
- return ((gpd->sbuffer_sflag & GP_STROKE_3DSPACE) && (*p->align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE)));
+ return ((gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) && (*p->align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE)));
}
/* ******************************************* */
@@ -241,38 +285,39 @@ static bool gpencil_project_check(tGPsdata *p)
static void gp_get_3d_reference(tGPsdata *p, float vec[3])
{
View3D *v3d = p->sa->spacedata.first;
- const float *fp = ED_view3d_cursor3d_get(p->scene, v3d)->location;
-
- /* the reference point used depends on the owner... */
-#if 0 /* XXX: disabled for now, since we can't draw relative to the owner yet */
+ Object *ob = NULL;
if (p->ownerPtr.type == &RNA_Object) {
- Object *ob = (Object *)p->ownerPtr.data;
-
- /* active Object
- * - use relative distance of 3D-cursor from object center
- */
- sub_v3_v3v3(vec, fp, ob->loc);
- }
- else
-#endif
- {
- /* use 3D-cursor */
- copy_v3_v3(vec, fp);
+ ob = (Object *)p->ownerPtr.data;
}
+ ED_gp_get_drawing_reference(v3d, p->scene, ob, p->gpl, *p->align_flag, vec);
}
/* Stroke Editing ---------------------------- */
-
/* check if the current mouse position is suitable for adding a new point */
static bool gp_stroke_filtermval(tGPsdata *p, const int mval[2], int pmval[2])
{
+ Brush *brush = p->brush;
int dx = abs(mval[0] - pmval[0]);
int dy = abs(mval[1] - pmval[1]);
+ brush->gpencil_settings->flag &= ~GP_BRUSH_STABILIZE_MOUSE_TEMP;
/* if buffer is empty, just let this go through (i.e. so that dots will work) */
- if (p->gpd->sbuffer_size == 0)
+ if (p->gpd->runtime.sbuffer_size == 0) {
return true;
-
+ }
+ /* if lazy mouse, check minimum distance */
+ else if (GPENCIL_LAZY_MODE(brush, p->shift)) {
+ brush->gpencil_settings->flag |= GP_BRUSH_STABILIZE_MOUSE_TEMP;
+ if ((dx * dx + dy * dy) > (brush->smooth_stroke_radius * brush->smooth_stroke_radius)) {
+ return true;
+ }
+ else {
+ /* If the mouse is moving within the radius of the last move,
+ * don't update the mouse position. This allows sharp turns. */
+ copy_v2_v2_int(p->mval, p->mvalo);
+ return false;
+ }
+ }
/* check if mouse moved at least certain distance on both axes (best case)
* - aims to eliminate some jitter-noise from input when trying to draw straight lines freehand
*/
@@ -291,47 +336,17 @@ static bool gp_stroke_filtermval(tGPsdata *p, const int mval[2], int pmval[2])
return false;
}
-/* reproject the points of the stroke to a plane locked to axis to avoid stroke offset */
-static void gp_project_points_to_plane(RegionView3D *rv3d, bGPDstroke *gps, const float origin[3], const int axis)
-{
- float plane_normal[3];
- float vn[3];
-
- float ray[3];
- float rpoint[3];
-
- /* normal vector for a plane locked to axis */
- zero_v3(plane_normal);
- plane_normal[axis] = 1.0f;
-
- /* Reproject the points in the plane */
- for (int i = 0; i < gps->totpoints; i++) {
- bGPDspoint *pt = &gps->points[i];
-
- /* get a vector from the point with the current view direction of the viewport */
- ED_view3d_global_to_vector(rv3d, &pt->x, vn);
-
- /* calculate line extrem point to create a ray that cross the plane */
- mul_v3_fl(vn, -50.0f);
- add_v3_v3v3(ray, &pt->x, vn);
-
- /* if the line never intersect, the point is not changed */
- if (isect_line_plane_v3(rpoint, &pt->x, ray, origin, plane_normal)) {
- copy_v3_v3(&pt->x, rpoint);
- }
- }
-}
-
/* reproject stroke to plane locked to axis in 3d cursor location */
static void gp_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
{
bGPdata *gpd = p->gpd;
+ Object *obact = (Object *)p->ownerPtr.data;
+
float origin[3];
- float cursor[3];
RegionView3D *rv3d = p->ar->regiondata;
/* verify the stroke mode is CURSOR 3d space mode */
- if ((gpd->sbuffer_sflag & GP_STROKE_3DSPACE) == 0) {
+ if ((gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) == 0) {
return;
}
if ((*p->align_flag & GP_PROJECT_VIEWSPACE) == 0) {
@@ -341,12 +356,9 @@ static void gp_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
return;
}
- /* get 3d cursor and set origin for locked axis only. Uses axis-1 because the enum for XYZ start with 1 */
- gp_get_3d_reference(p, cursor);
- zero_v3(origin);
- origin[p->lock_axis - 1] = cursor[p->lock_axis - 1];
-
- gp_project_points_to_plane(rv3d, gps, origin, p->lock_axis - 1);
+ /* get drawing origin */
+ gp_get_3d_reference(p, origin);
+ ED_gp_project_stroke_to_plane(obact, rv3d, gps, origin, p->lock_axis - 1);
}
/* convert screen-coordinates to buffer-coordinates */
@@ -356,7 +368,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
bGPdata *gpd = p->gpd;
/* in 3d-space - pt->x/y/z are 3 side-by-side floats */
- if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) {
+ if (gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) {
if (gpencil_project_check(p) && (ED_view3d_autodist_simple(p->ar, mval, out, 0, depth))) {
/* projecting onto 3D-Geometry
* - nothing more needs to be done here, since view_autodist_simple() has already done it
@@ -365,7 +377,8 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
else {
float mval_prj[2];
float rvec[3], dvec[3];
- float mval_f[2] = {UNPACK2(mval)};
+ float mval_f[2];
+ copy_v2fl_v2i(mval_f, mval);
float zfac;
/* Current method just converts each point in screen-coordinates to
@@ -390,42 +403,23 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
}
}
}
-
- /* 2d - on 'canvas' (assume that p->v2d is set) */
- else if ((gpd->sbuffer_sflag & GP_STROKE_2DSPACE) && (p->v2d)) {
- UI_view2d_region_to_view(p->v2d, mval[0], mval[1], &out[0], &out[1]);
- mul_v3_m4v3(out, p->imat, out);
- }
-
- /* 2d - relative to screen (viewport area) */
- else {
- if (p->subrect == NULL) { /* normal 3D view */
- out[0] = (float)(mval[0]) / (float)(p->ar->winx) * 100;
- out[1] = (float)(mval[1]) / (float)(p->ar->winy) * 100;
- }
- else { /* camera view, use subrect */
- out[0] = ((mval[0] - p->subrect->xmin) / BLI_rctf_size_x(p->subrect)) * 100;
- out[1] = ((mval[1] - p->subrect->ymin) / BLI_rctf_size_y(p->subrect)) * 100;
- }
- }
}
/* apply jitter to stroke */
-static void gp_brush_jitter(
- bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const int mval[2], int r_mval[2], RNG *rng)
+static void gp_brush_jitter(bGPdata *gpd, Brush *brush, tGPspoint *pt, const int mval[2], int r_mval[2], RNG *rng)
{
float pressure = pt->pressure;
float tmp_pressure = pt->pressure;
- if (brush->draw_jitter > 0.0f) {
- float curvef = curvemapping_evaluateF(brush->cur_jitter, 0, pressure);
- tmp_pressure = curvef * brush->draw_sensitivity;
+ if (brush->gpencil_settings->draw_jitter > 0.0f) {
+ float curvef = curvemapping_evaluateF(brush->gpencil_settings->curve_jitter, 0, pressure);
+ tmp_pressure = curvef * brush->gpencil_settings->draw_sensitivity;
}
- const float exfactor = (brush->draw_jitter + 2.0f) * (brush->draw_jitter + 2.0f); /* exponential value */
+ const float exfactor = (brush->gpencil_settings->draw_jitter + 2.0f) * (brush->gpencil_settings->draw_jitter + 2.0f); /* exponential value */
const float fac = BLI_rng_get_float(rng) * exfactor * tmp_pressure;
/* Jitter is applied perpendicular to the mouse movement vector (2D space) */
float mvec[2], svec[2];
/* mouse movement in ints -> floats */
- if (gpd->sbuffer_size > 1) {
+ if (gpd->runtime.sbuffer_size > 1) {
mvec[0] = (float)(mval[0] - (pt - 1)->x);
mvec[1] = (float)(mval[1] - (pt - 1)->y);
normalize_v2(mvec);
@@ -451,18 +445,18 @@ static void gp_brush_jitter(
}
/* apply pressure change depending of the angle of the stroke to simulate a pen with shape */
-static void gp_brush_angle(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const int mval[2])
+static void gp_brush_angle(bGPdata *gpd, Brush *brush, tGPspoint *pt, const int mval[2])
{
float mvec[2];
- float sen = brush->draw_angle_factor; /* sensitivity */;
+ float sen = brush->gpencil_settings->draw_angle_factor; /* sensitivity */;
float fac;
float mpressure;
- float angle = brush->draw_angle; /* default angle of brush in radians */;
+ float angle = brush->gpencil_settings->draw_angle; /* default angle of brush in radians */;
float v0[2] = { cos(angle), sin(angle) }; /* angle vector of the brush with full thickness */
/* Apply to first point (only if there are 2 points because before no data to do it ) */
- if (gpd->sbuffer_size == 1) {
+ if (gpd->runtime.sbuffer_size == 1) {
mvec[0] = (float)(mval[0] - (pt - 1)->x);
mvec[1] = (float)(mval[1] - (pt - 1)->y);
normalize_v2(mvec);
@@ -475,7 +469,7 @@ static void gp_brush_angle(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const
}
/* apply from second point */
- if (gpd->sbuffer_size >= 1) {
+ if (gpd->runtime.sbuffer_size >= 1) {
mvec[0] = (float)(mval[0] - (pt - 1)->x);
mvec[1] = (float)(mval[1] - (pt - 1)->y);
normalize_v2(mvec);
@@ -490,21 +484,83 @@ static void gp_brush_angle(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const
}
+/* Apply smooth to buffer while drawing
+* to smooth point C, use 2 before (A, B) and current point (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)
+{
+ bGPdata *gpd = p->gpd;
+ short num_points = gpd->runtime.sbuffer_size;
+
+ /* Do nothing if not enough points to smooth out */
+ if ((num_points < 3) || (idx < 3) || (inf == 0.0f)) {
+ return;
+ }
+
+ tGPspoint *points = (tGPspoint *)gpd->runtime.sbuffer;
+ float steps = 4.0f;
+ if (idx < 4) {
+ steps--;
+ }
+
+ tGPspoint *pta = idx >= 4 ? &points[idx - 4] : NULL;
+ tGPspoint *ptb = idx >= 3 ? &points[idx - 3] : NULL;
+ tGPspoint *ptc = idx >= 2 ? &points[idx - 2] : NULL;
+ tGPspoint *ptd = &points[idx - 1];
+
+ float sco[2] = { 0.0f };
+ float a[2], b[2], c[2], d[2];
+ const float average_fac = 1.0f / steps;
+
+ /* Compute smoothed coordinate by taking the ones nearby */
+ if (pta) {
+ copy_v2fl_v2i(a, &pta->x);
+ madd_v2_v2fl(sco, a, average_fac);
+ }
+ if (ptb) {
+ copy_v2fl_v2i(b, &ptb->x);
+ madd_v2_v2fl(sco, b, average_fac);
+ }
+ if (ptc) {
+ copy_v2fl_v2i(c, &ptc->x);
+ madd_v2_v2fl(sco, c, average_fac);
+ }
+ if (ptd) {
+ copy_v2fl_v2i(d, &ptd->x);
+ madd_v2_v2fl(sco, d, average_fac);
+ }
+
+ /* Based on influence factor, blend between original and optimal smoothed coordinate */
+ interp_v2_v2v2(c, c, sco, inf);
+ round_v2i_v2fl(&ptc->x, c);
+}
+
/* add current stroke-point to buffer (returns whether point was successfully added) */
static short gp_stroke_addpoint(
tGPsdata *p, const int mval[2], float pressure, double curtime)
{
bGPdata *gpd = p->gpd;
- bGPDbrush *brush = p->brush;
+ Brush *brush = p->brush;
tGPspoint *pt;
ToolSettings *ts = p->scene->toolsettings;
+ Object *obact = (Object *)p->ownerPtr.data;
+ Depsgraph *depsgraph = p->depsgraph; \
+ RegionView3D *rv3d = p->ar->regiondata;
+ View3D *v3d = p->sa->spacedata.first;
+ MaterialGPencilStyle *gp_style = p->material->gp_style;
/* check painting mode */
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
/* straight lines only - i.e. only store start and end point in buffer */
- if (gpd->sbuffer_size == 0) {
+ if (gpd->runtime.sbuffer_size == 0) {
/* first point in buffer (start point) */
- pt = (tGPspoint *)(gpd->sbuffer);
+ pt = (tGPspoint *)(gpd->runtime.sbuffer);
/* store settings */
copy_v2_v2_int(&pt->x, mval);
@@ -513,13 +569,13 @@ static short gp_stroke_addpoint(
pt->time = (float)(curtime - p->inittime);
/* increment buffer size */
- gpd->sbuffer_size++;
+ gpd->runtime.sbuffer_size++;
}
else {
/* just reset the endpoint to the latest value
* - assume that pointers for this are always valid...
*/
- pt = ((tGPspoint *)(gpd->sbuffer) + 1);
+ pt = ((tGPspoint *)(gpd->runtime.sbuffer) + 1);
/* store settings */
copy_v2_v2_int(&pt->x, mval);
@@ -528,31 +584,35 @@ static short gp_stroke_addpoint(
pt->time = (float)(curtime - p->inittime);
/* now the buffer has 2 points (and shouldn't be allowed to get any larger) */
- gpd->sbuffer_size = 2;
+ gpd->runtime.sbuffer_size = 2;
}
+ /* tag depsgraph to update object */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
/* can keep carrying on this way :) */
return GP_STROKEADD_NORMAL;
}
else if (p->paintmode == GP_PAINTMODE_DRAW) { /* normal drawing */
/* check if still room in buffer */
- if (gpd->sbuffer_size >= GP_STROKE_BUFFER_MAX)
+ if (gpd->runtime.sbuffer_size >= GP_STROKE_BUFFER_MAX)
return GP_STROKEADD_OVERFLOW;
/* get pointer to destination point */
- pt = ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size);
+ pt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_size);
/* store settings */
/* pressure */
- if (brush->flag & GP_BRUSH_USE_PRESSURE) {
- float curvef = curvemapping_evaluateF(brush->cur_sensitivity, 0, pressure);
- pt->pressure = curvef * brush->draw_sensitivity;
+ if (brush->gpencil_settings->flag & GP_BRUSH_USE_PRESSURE) {
+ float curvef = curvemapping_evaluateF(brush->gpencil_settings->curve_sensitivity, 0, pressure);
+ pt->pressure = curvef * brush->gpencil_settings->draw_sensitivity;
}
else {
pt->pressure = 1.0f;
}
+
/* Apply jitter to position */
- if (brush->draw_jitter > 0.0f) {
+ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && (brush->gpencil_settings->draw_jitter > 0.0f)) {
int r_mval[2];
gp_brush_jitter(gpd, brush, pt, mval, r_mval, p->rng);
copy_v2_v2_int(&pt->x, r_mval);
@@ -561,42 +621,62 @@ static short gp_stroke_addpoint(
copy_v2_v2_int(&pt->x, mval);
}
/* apply randomness to pressure */
- if ((brush->draw_random_press > 0.0f) && (brush->flag & GP_BRUSH_USE_RANDOM_PRESSURE)) {
- float curvef = curvemapping_evaluateF(brush->cur_sensitivity, 0, pressure);
- float tmp_pressure = curvef * brush->draw_sensitivity;
+ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) &&
+ (brush->gpencil_settings->draw_random_press > 0.0f))
+ {
+ float curvef = curvemapping_evaluateF(brush->gpencil_settings->curve_sensitivity, 0, pressure);
+ float tmp_pressure = curvef * brush->gpencil_settings->draw_sensitivity;
if (BLI_rng_get_float(p->rng) > 0.5f) {
- pt->pressure -= tmp_pressure * brush->draw_random_press * BLI_rng_get_float(p->rng);
+ pt->pressure -= tmp_pressure * brush->gpencil_settings->draw_random_press * BLI_rng_get_float(p->rng);
}
else {
- pt->pressure += tmp_pressure * brush->draw_random_press * BLI_rng_get_float(p->rng);
+ pt->pressure += tmp_pressure * brush->gpencil_settings->draw_random_press * BLI_rng_get_float(p->rng);
}
CLAMP(pt->pressure, GPENCIL_STRENGTH_MIN, 1.0f);
}
+ /* apply randomness to uv texture rotation */
+ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && (brush->gpencil_settings->uv_random > 0.0f)) {
+ if (BLI_rng_get_float(p->rng) > 0.5f) {
+ pt->uv_rot = (BLI_rng_get_float(p->rng) * M_PI * -1) * brush->gpencil_settings->uv_random;
+ }
+ else {
+ pt->uv_rot = (BLI_rng_get_float(p->rng) * M_PI) * brush->gpencil_settings->uv_random;
+ }
+ CLAMP(pt->uv_rot, -M_PI_2, M_PI_2);
+ }
+ else {
+ pt->uv_rot = 0.0f;
+ }
+
/* apply angle of stroke to brush size */
- if (brush->draw_angle_factor > 0.0f) {
+ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) &&
+ (brush->gpencil_settings->draw_angle_factor > 0.0f))
+ {
gp_brush_angle(gpd, brush, pt, mval);
}
/* color strength */
- if (brush->flag & GP_BRUSH_USE_STENGTH_PRESSURE) {
- float curvef = curvemapping_evaluateF(brush->cur_strength, 0, pressure);
- float tmp_pressure = curvef * brush->draw_sensitivity;
+ if (brush->gpencil_settings->flag & GP_BRUSH_USE_STENGTH_PRESSURE) {
+ float curvef = curvemapping_evaluateF(brush->gpencil_settings->curve_strength, 0, pressure);
+ float tmp_pressure = curvef * brush->gpencil_settings->draw_sensitivity;
- pt->strength = tmp_pressure * brush->draw_strength;
+ pt->strength = tmp_pressure * brush->gpencil_settings->draw_strength;
}
else {
- pt->strength = brush->draw_strength;
+ pt->strength = brush->gpencil_settings->draw_strength;
}
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
/* apply randomness to color strength */
- if ((brush->draw_random_press > 0.0f) && (brush->flag & GP_BRUSH_USE_RANDOM_STRENGTH)) {
+ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) &&
+ (brush->gpencil_settings->draw_random_strength > 0.0f))
+ {
if (BLI_rng_get_float(p->rng) > 0.5f) {
- pt->strength -= pt->strength * brush->draw_random_press * BLI_rng_get_float(p->rng);
+ pt->strength -= pt->strength * brush->gpencil_settings->draw_random_strength * BLI_rng_get_float(p->rng);
}
else {
- pt->strength += pt->strength * brush->draw_random_press * BLI_rng_get_float(p->rng);
+ pt->strength += pt->strength * brush->gpencil_settings->draw_random_strength * BLI_rng_get_float(p->rng);
}
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
}
@@ -604,11 +684,49 @@ static short gp_stroke_addpoint(
/* point time */
pt->time = (float)(curtime - p->inittime);
+ /* point uv (only 3d view) */
+ if ((p->sa->spacetype == SPACE_VIEW3D) && (gpd->runtime.sbuffer_size > 1)) {
+ float pixsize = gp_style->texture_pixsize / 1000000.0f;
+ tGPspoint *ptb = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_size - 2;
+ bGPDspoint spt, spt2;
+
+ /* get origin to reproject point */
+ float origin[3];
+ gp_get_3d_reference(p, origin);
+ /* reproject current */
+ ED_gpencil_tpoint_to_point(p->ar, origin, pt, &spt);
+ ED_gp_project_point_to_plane(obact, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &spt);
+
+ /* reproject previous */
+ ED_gpencil_tpoint_to_point(p->ar, origin, ptb, &spt2);
+ ED_gp_project_point_to_plane(obact, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &spt2);
+
+ p->totpixlen += len_v3v3(&spt.x, &spt2.x) / pixsize;
+ pt->uv_fac = p->totpixlen;
+ if ((gp_style) && (gp_style->sima)) {
+ pt->uv_fac /= gp_style->sima->gen_x;
+ }
+ }
+ else {
+ p->totpixlen = 0.0f;
+ pt->uv_fac = 0.0f;
+ }
+
/* increment counters */
- gpd->sbuffer_size++;
+ gpd->runtime.sbuffer_size++;
+
+ /* 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_size - s);
+ }
+ }
+
+ /* tag depsgraph to update object */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
/* check if another operation can still occur */
- if (gpd->sbuffer_size == GP_STROKE_BUFFER_MAX)
+ if (gpd->runtime.sbuffer_size == GP_STROKE_BUFFER_MAX)
return GP_STROKEADD_FULL;
else
return GP_STROKEADD_NORMAL;
@@ -617,7 +735,7 @@ static short gp_stroke_addpoint(
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
/* get pointer to destination point */
- pt = (tGPspoint *)(gpd->sbuffer);
+ pt = (tGPspoint *)(gpd->runtime.sbuffer);
/* store settings */
copy_v2_v2_int(&pt->x, mval);
@@ -632,14 +750,17 @@ static short gp_stroke_addpoint(
if (gp_stroke_added_check(p)) {
bGPDstroke *gps = p->gpf->strokes.last;
bGPDspoint *pts;
+ MDeformVert *dvert;
/* first time point is adding to temporary buffer -- need to allocate new point in stroke */
- if (gpd->sbuffer_size == 0) {
+ if (gpd->runtime.sbuffer_size == 0) {
gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1));
+ gps->dvert = MEM_reallocN(gps->dvert, sizeof(MDeformVert) * (gps->totpoints + 1));
gps->totpoints++;
}
pts = &gps->points[gps->totpoints - 1];
+ dvert = &gps->dvert[gps->totpoints - 1];
/* special case for poly lines: normally,
* depth is needed only when creating new stroke from buffer,
@@ -647,8 +768,6 @@ static short gp_stroke_addpoint(
* so initialize depth buffer before converting coordinates
*/
if (gpencil_project_check(p)) {
- View3D *v3d = p->sa->spacedata.first;
-
view3d_region_operator_needs_opengl(p->win, p->ar);
ED_view3d_autodist_init(
p->depsgraph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
@@ -656,25 +775,32 @@ static short gp_stroke_addpoint(
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &pt->x, &pts->x, NULL);
- /* if axis locked, reproject to plane locked (only in 3d space) */
- if (p->lock_axis > GP_LOCKAXIS_NONE) {
- gp_reproject_toplane(p, gps);
- }
+ /* reproject to plane (only in 3d space) */
+ gp_reproject_toplane(p, gps);
/* if parented change position relative to parent object */
- if (gpl->parent != NULL) {
- gp_apply_parent_point(gpl, pts);
- }
+ gp_apply_parent_point(depsgraph, obact, gpd, gpl, pts);
/* copy pressure and time */
pts->pressure = pt->pressure;
pts->strength = pt->strength;
pts->time = pt->time;
+ pts->uv_fac = pt->uv_fac;
+ pts->uv_rot = pt->uv_rot;
+
+ dvert->totweight = 0;
+ dvert->dw = NULL;
+
/* force fill recalc */
gps->flag |= GP_STROKE_RECALC_CACHES;
+ /* drawing batch cache is dirty now */
+ gp_update_cache(p->gpd);
}
/* increment counters */
- if (gpd->sbuffer_size == 0)
- gpd->sbuffer_size++;
+ if (gpd->runtime.sbuffer_size == 0)
+ gpd->runtime.sbuffer_size++;
+
+ /* tag depsgraph to update object */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
return GP_STROKEADD_NORMAL;
}
@@ -690,9 +816,9 @@ static short gp_stroke_addpoint(
static void gp_stroke_simplify(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
- tGPspoint *old_points = (tGPspoint *)gpd->sbuffer;
- short num_points = gpd->sbuffer_size;
- short flag = gpd->sbuffer_sflag;
+ tGPspoint *old_points = (tGPspoint *)gpd->runtime.sbuffer;
+ short num_points = gpd->runtime.sbuffer_size;
+ short flag = gpd->runtime.sbuffer_sflag;
short i, j;
/* only simplify if simplification is enabled, and we're not doing a straight line */
@@ -707,9 +833,9 @@ static void gp_stroke_simplify(tGPsdata *p)
* - firstly set sbuffer to NULL, so a new one is allocated
* - secondly, reset flag after, as it gets cleared auto
*/
- gpd->sbuffer = NULL;
+ gpd->runtime.sbuffer = NULL;
gp_session_validatebuffer(p);
- gpd->sbuffer_sflag = flag;
+ gpd->runtime.sbuffer_sflag = flag;
/* macro used in loop to get position of new point
* - used due to the mixture of datatypes in use here
@@ -766,8 +892,11 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
bGPDstroke *gps;
bGPDspoint *pt;
tGPspoint *ptc;
- bGPDbrush *brush = p->brush;
+ MDeformVert *dvert;
+ Brush *brush = p->brush;
ToolSettings *ts = p->scene->toolsettings;
+ Depsgraph *depsgraph = p->depsgraph;
+ Object *obact = (Object *)p->ownerPtr.data;
int i, totelem;
/* since strokes are so fine, when using their depth we need a margin otherwise they might get missed */
@@ -777,14 +906,14 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
* - drawing straight-lines only requires the endpoints
*/
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT)
- totelem = (gpd->sbuffer_size >= 2) ? 2 : gpd->sbuffer_size;
+ totelem = (gpd->runtime.sbuffer_size >= 2) ? 2 : gpd->runtime.sbuffer_size;
else
- totelem = gpd->sbuffer_size;
+ totelem = gpd->runtime.sbuffer_size;
/* exit with error if no valid points from this stroke */
if (totelem == 0) {
if (G.debug & G_DEBUG)
- printf("Error: No valid points in stroke buffer to convert (tot=%d)\n", gpd->sbuffer_size);
+ printf("Error: No valid points in stroke buffer to convert (tot=%d)\n", gpd->runtime.sbuffer_size);
return;
}
@@ -793,6 +922,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
* interactive behavior
*/
if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
+ /* be sure to hide any lazy cursor */
+ ED_gpencil_toggle_brush_cursor(p->C, true, NULL);
+
if (gp_stroke_added_check(p)) {
return;
}
@@ -803,95 +935,94 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* copy appropriate settings for stroke */
gps->totpoints = totelem;
- gps->thickness = brush->thickness;
- gps->flag = gpd->sbuffer_sflag;
+ gps->thickness = brush->size;
+ gps->flag = gpd->runtime.sbuffer_sflag;
gps->inittime = p->inittime;
/* enable recalculation flag by default (only used if hq fill) */
gps->flag |= GP_STROKE_RECALC_CACHES;
/* allocate enough memory for a continuous array for storage points */
- int sublevel = brush->sublevel;
- int new_totpoints = gps->totpoints;
+ const int subdivide = brush->gpencil_settings->draw_subdivide;
+
+ gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights");
- for (i = 0; i < sublevel; i++) {
- new_totpoints += new_totpoints - 1;
- }
- gps->points = MEM_callocN(sizeof(bGPDspoint) * new_totpoints, "gp_stroke_points");
/* initialize triangle memory to dummy data */
gps->triangles = MEM_callocN(sizeof(bGPDtriangle), "GP Stroke triangulation");
gps->flag |= GP_STROKE_RECALC_CACHES;
gps->tot_triangles = 0;
+ /* drawing batch cache is dirty now */
+ gp_update_cache(p->gpd);
/* set pointer to first non-initialized point */
pt = gps->points + (gps->totpoints - totelem);
+ dvert = gps->dvert + (gps->totpoints - totelem);
/* copy points from the buffer to the stroke */
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
/* straight lines only -> only endpoints */
{
/* first point */
- ptc = gpd->sbuffer;
+ ptc = gpd->runtime.sbuffer;
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
- /* if axis locked, reproject to plane locked (only in 3d space) */
- if (p->lock_axis > GP_LOCKAXIS_NONE) {
- gp_reproject_toplane(p, gps);
- }
- /* if parented change position relative to parent object */
- if (gpl->parent != NULL) {
- gp_apply_parent_point(gpl, pt);
- }
/* copy pressure and time */
pt->pressure = ptc->pressure;
pt->strength = ptc->strength;
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
pt->time = ptc->time;
+ dvert->totweight = 0;
+ dvert->dw = NULL;
+
pt++;
+ dvert++;
}
if (totelem == 2) {
/* last point if applicable */
- ptc = ((tGPspoint *)gpd->sbuffer) + (gpd->sbuffer_size - 1);
+ ptc = ((tGPspoint *)gpd->runtime.sbuffer) + (gpd->runtime.sbuffer_size - 1);
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
- /* if axis locked, reproject to plane locked (only in 3d space) */
- if (p->lock_axis > GP_LOCKAXIS_NONE) {
- gp_reproject_toplane(p, gps);
- }
- /* if parented change position relative to parent object */
- if (gpl->parent != NULL) {
- gp_apply_parent_point(gpl, pt);
- }
-
/* copy pressure and time */
pt->pressure = ptc->pressure;
pt->strength = ptc->strength;
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
pt->time = ptc->time;
+
+ dvert->totweight = 0;
+ dvert->dw = NULL;
+ }
+
+ /* reproject to plane (only in 3d space) */
+ gp_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, gpd, gpl, pt);
}
}
else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
/* first point */
- ptc = gpd->sbuffer;
+ ptc = gpd->runtime.sbuffer;
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
- /* if axis locked, reproject to plane locked (only in 3d space) */
- if (p->lock_axis > GP_LOCKAXIS_NONE) {
- gp_reproject_toplane(p, gps);
- }
+ /* reproject to plane (only in 3d space) */
+ gp_reproject_toplane(p, gps);
/* if parented change position relative to parent object */
- if (gpl->parent != NULL) {
- gp_apply_parent_point(gpl, pt);
- }
+ gp_apply_parent_point(depsgraph, obact, gpd, gpl, pt);
/* copy pressure and time */
pt->pressure = ptc->pressure;
pt->strength = ptc->strength;
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
pt->time = ptc->time;
+
+ dvert->totweight = 0;
+ dvert->dw = NULL;
+
}
else {
float *depth_arr = NULL;
@@ -902,9 +1033,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
int interp_depth = 0;
int found_depth = 0;
- depth_arr = MEM_mallocN(sizeof(float) * gpd->sbuffer_size, "depth_points");
+ depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_size, "depth_points");
- for (i = 0, ptc = gpd->sbuffer; i < gpd->sbuffer_size; i++, ptc++, pt++) {
+ for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size; i++, ptc++, pt++) {
copy_v2_v2_int(mval, &ptc->x);
if ((ED_view3d_autodist_depth(p->ar, mval, depth_margin, depth_arr + i) == 0) &&
@@ -921,7 +1052,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
if (found_depth == false) {
/* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */
- for (i = gpd->sbuffer_size - 1; i >= 0; i--)
+ for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--)
depth_arr[i] = 0.9999f;
}
else {
@@ -930,13 +1061,13 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
int first_valid = 0;
int last_valid = 0;
- for (i = 0; i < gpd->sbuffer_size; i++) {
+ for (i = 0; i < gpd->runtime.sbuffer_size; i++) {
if (depth_arr[i] != FLT_MAX)
break;
}
first_valid = i;
- for (i = gpd->sbuffer_size - 1; i >= 0; i--) {
+ for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) {
if (depth_arr[i] != FLT_MAX)
break;
}
@@ -950,16 +1081,15 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
}
if (interp_depth) {
- interp_sparse_array(depth_arr, gpd->sbuffer_size, FLT_MAX);
+ interp_sparse_array(depth_arr, gpd->runtime.sbuffer_size, FLT_MAX);
}
}
}
-
pt = gps->points;
/* convert all points (normal behavior) */
- for (i = 0, ptc = gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++, pt++) {
+ for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size && 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);
@@ -968,20 +1098,18 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
pt->strength = ptc->strength;
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
pt->time = ptc->time;
+ pt->uv_fac = ptc->uv_fac;
+ pt->uv_rot = ptc->uv_rot;
}
- /* subdivide the stroke */
- if (sublevel > 0) {
- int totpoints = gps->totpoints;
- for (i = 0; i < sublevel; i++) {
- /* we're adding one new point between each pair of verts on each step */
- totpoints += totpoints - 1;
-
- gp_subdivide_stroke(gps, totpoints);
- }
+ /* subdivide and smooth the stroke */
+ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) && (subdivide > 0)) {
+ gp_subdivide_stroke(gps, subdivide);
}
/* apply randomness to stroke */
- if (brush->draw_random_sub > 0.0f) {
+ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) &&
+ (brush->gpencil_settings->draw_random_sub > 0.0f))
+ {
gp_randomize_stroke(gps, brush, p->rng);
}
@@ -989,34 +1117,43 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
* for each iteration, the factor is reduced to get a better smoothing without changing too much
* the original stroke
*/
- if (brush->draw_smoothfac > 0.0f) {
+ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) &&
+ (brush->gpencil_settings->draw_smoothfac > 0.0f))
+ {
float reduce = 0.0f;
- for (int r = 0; r < brush->draw_smoothlvl; ++r) {
+ for (int r = 0; r < brush->gpencil_settings->draw_smoothlvl; r++) {
for (i = 0; i < gps->totpoints; i++) {
- /* NOTE: No pressure smoothing, or else we get annoying thickness changes while drawing... */
- gp_smooth_stroke(gps, i, brush->draw_smoothfac - reduce, false);
+ BKE_gpencil_smooth_stroke(gps, i, brush->gpencil_settings->draw_smoothfac - reduce);
+ BKE_gpencil_smooth_stroke_strength(gps, i, brush->gpencil_settings->draw_smoothfac);
}
reduce += 0.25f; // reduce the factor
}
}
-
- /* if axis locked, reproject to plane locked (only in 3d space) */
- if (p->lock_axis > GP_LOCKAXIS_NONE) {
- gp_reproject_toplane(p, gps);
- }
- /* if parented change position relative to parent object */
- if (gpl->parent != NULL) {
- gp_apply_parent(gpl, gps);
+ /* smooth thickness */
+ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) &&
+ (brush->gpencil_settings->thick_smoothfac > 0.0f))
+ {
+ for (int r = 0; r < brush->gpencil_settings->thick_smoothlvl * 2; r++) {
+ for (i = 0; i < gps->totpoints; i++) {
+ BKE_gpencil_smooth_stroke_thickness(gps, i, brush->gpencil_settings->thick_smoothfac);
+ }
+ }
}
+ /* reproject to plane (only in 3d space) */
+ gp_reproject_toplane(p, gps);
+ /* change position relative to parent object */
+ gp_apply_parent(depsgraph, obact, gpd, gpl, gps);
+
if (depth_arr)
MEM_freeN(depth_arr);
}
- /* Save palette color */
- bGPDpalette *palette = BKE_gpencil_palette_getactive(p->gpd);
- bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette);
- gps->palcolor = palcolor;
- BLI_strncpy(gps->colorname, palcolor->info, sizeof(gps->colorname));
+
+ /* Save material index */
+ gps->mat_nr = BKE_gpencil_get_material_index(p->ob, p->material) - 1;
+
+ /* calculate UVs along the stroke */
+ ED_gpencil_calc_stroke_uv(obact, gps);
/* add stroke to frame, usually on tail of the listbase, but if on back is enabled the stroke is added on listbase head
* because the drawing order is inverse and the head stroke is the first to draw. This is very useful for artist
@@ -1047,6 +1184,8 @@ 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)
{
+ Object *obact = (Object *)p->ownerPtr.data;
+
if ((p->sa->spacetype == SPACE_VIEW3D) &&
(p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH))
{
@@ -1059,7 +1198,7 @@ static bool gp_stroke_eraser_is_occluded(tGPsdata *p, const bGPDspoint *pt, cons
float diff_mat[4][4];
/* calculate difference matrix if parent object */
- ED_gpencil_parent_location(gpl, diff_mat);
+ ED_gpencil_parent_location(p->depsgraph, obact, p->gpd, gpl, diff_mat);
if (ED_view3d_autodist_simple(p->ar, mval, mval_3d, 0, NULL)) {
const float depth_mval = view3d_point_depth(rv3d, mval_3d);
@@ -1092,6 +1231,24 @@ static float gp_stroke_eraser_calc_influence(tGPsdata *p, const int mval[2], con
return fac;
}
+/* helper to free a stroke */
+static void gp_free_stroke(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps)
+{
+ if (gps->points) {
+ MEM_freeN(gps->points);
+ }
+
+ if (gps->dvert) {
+ BKE_gpencil_free_stroke_weights(gps);
+ MEM_freeN(gps->dvert);
+ }
+
+ if (gps->triangles)
+ MEM_freeN(gps->triangles);
+ BLI_freelinkN(&gpf->strokes, gps);
+ gp_update_cache(gpd);
+}
+
/* eraser tool - evaluation per stroke */
/* TODO: this could really do with some optimization (KD-Tree/BVH?) */
static void gp_stroke_eraser_dostroke(tGPsdata *p,
@@ -1099,46 +1256,58 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
const int mval[2], const int mvalo[2],
const int radius, const rcti *rect)
{
+ Depsgraph *depsgraph = p->depsgraph;
+ Object *obact = (Object *)p->ownerPtr.data;
+ Brush *eraser = p->eraser;
bGPDspoint *pt1, *pt2;
int pc1[2] = {0};
int pc2[2] = {0};
int i;
float diff_mat[4][4];
- /* calculate difference matrix if parent object */
- if (gpl->parent != NULL) {
- ED_gpencil_parent_location(gpl, diff_mat);
- }
+ /* calculate difference matrix */
+ ED_gpencil_parent_location(depsgraph, obact, p->gpd, gpl, diff_mat);
if (gps->totpoints == 0) {
/* just free stroke */
- if (gps->points)
- MEM_freeN(gps->points);
- if (gps->triangles)
- MEM_freeN(gps->triangles);
- BLI_freelinkN(&gpf->strokes, gps);
+ gp_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)) {
- if (gpl->parent == NULL) {
- gp_point_to_xy(&p->gsc, gps, gps->points, &pc1[0], &pc1[1]);
- }
- else {
- bGPDspoint pt_temp;
- gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
- gp_point_to_xy(&p->gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
+ bGPDspoint pt_temp;
+ gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
+ gp_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, pc1) <= radius) {
+ /* free stroke */
+ gp_free_stroke(p->gpd, gpf, gps);
+ }
}
+ }
+ }
+ else if ((p->flags & GP_PAINTFLAG_STROKE_ERASER) || (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_STROKE)) {
+ for (i = 0; (i + 1) < gps->totpoints; i++) {
+
+ /* only process if it hasn't been masked out... */
+ if ((p->flags & GP_PAINTFLAG_SELECTMASK) && !(gps->points->flag & GP_SPOINT_SELECT))
+ continue;
+
+ /* get points to work with */
+ pt1 = gps->points + i;
+ bGPDspoint npt;
+ gp_point_to_parent_space(pt1, diff_mat, &npt);
+ gp_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, pc1) <= radius) {
/* free stroke */
- // XXX: pressure sensitive eraser should apply here too?
- MEM_freeN(gps->points);
- if (gps->triangles)
- MEM_freeN(gps->triangles);
- BLI_freelinkN(&gpf->strokes, gps);
+ gp_free_stroke(p->gpd, gpf, gps);
+ return;
}
}
}
@@ -1181,18 +1350,12 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
if ((p->flags & GP_PAINTFLAG_SELECTMASK) && !(gps->points->flag & GP_SPOINT_SELECT))
continue;
- if (gpl->parent == NULL) {
- gp_point_to_xy(&p->gsc, gps, pt1, &pc1[0], &pc1[1]);
- gp_point_to_xy(&p->gsc, gps, pt2, &pc2[0], &pc2[1]);
- }
- else {
- bGPDspoint npt;
- gp_point_to_parent_space(pt1, diff_mat, &npt);
- gp_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]);
+ bGPDspoint npt;
+ gp_point_to_parent_space(pt1, diff_mat, &npt);
+ gp_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]);
- gp_point_to_parent_space(pt2, diff_mat, &npt);
- gp_point_to_xy(&p->gsc, gps, &npt, &pc2[0], &pc2[1]);
- }
+ gp_point_to_parent_space(pt2, diff_mat, &npt);
+ gp_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, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
@@ -1215,11 +1378,15 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
pt2->pressure -= gp_stroke_eraser_calc_influence(p, mval, radius, pc2) * strength / 2.0f;
/* 2) Tag any point with overly low influence for removal in the next pass */
- if (pt1->pressure < cull_thresh) {
+ if ((pt1->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) ||
+ (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD))
+ {
pt1->flag |= GP_SPOINT_TAG;
do_cull = true;
}
- if (pt2->pressure < cull_thresh) {
+ if ((pt2->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) ||
+ (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD))
+ {
pt2->flag |= GP_SPOINT_TAG;
do_cull = true;
}
@@ -1230,8 +1397,9 @@ 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);
+ gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false);
}
+ gp_update_cache(p->gpd);
}
}
@@ -1275,7 +1443,7 @@ static void gp_stroke_doeraser(tGPsdata *p)
for (gps = gpf->strokes.first; gps; gps = gpn) {
gpn = gps->next;
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
+ if (ED_gpencil_stroke_color_use(p->ob, gpl, gps) == false) {
continue;
}
/* Not all strokes in the datablock may be valid in the current editor/context
@@ -1295,107 +1463,178 @@ static void gp_stroke_doeraser(tGPsdata *p)
static void gp_session_validatebuffer(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
+ Brush *brush = p->brush;
/* clear memory of buffer (or allocate it if starting a new session) */
- if (gpd->sbuffer) {
+ if (gpd->runtime.sbuffer) {
/* printf("\t\tGP - reset sbuffer\n"); */
- memset(gpd->sbuffer, 0, sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX);
+ memset(gpd->runtime.sbuffer, 0, sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX);
}
else {
/* printf("\t\tGP - allocate sbuffer\n"); */
- gpd->sbuffer = MEM_callocN(sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
+ gpd->runtime.sbuffer = MEM_callocN(sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
}
/* reset indices */
- gpd->sbuffer_size = 0;
+ gpd->runtime.sbuffer_size = 0;
/* reset flags */
- gpd->sbuffer_sflag = 0;
+ gpd->runtime.sbuffer_sflag = 0;
/* reset inittime */
p->inittime = 0.0;
+
+ /* reset lazy */
+ if (brush) {
+ brush->gpencil_settings->flag &= ~GP_BRUSH_STABILIZE_MOUSE_TEMP;
+ }
}
-/* create a new palette color */
-static bGPDpalettecolor *gp_create_new_color(bGPDpalette *palette)
+/* helper to get default eraser and create one if no eraser brush */
+static Brush *gp_get_default_eraser(Main *bmain, ToolSettings *ts)
{
- bGPDpalettecolor *palcolor;
+ Brush *brush_dft = NULL;
+ Paint *paint = BKE_brush_get_gpencil_paint(ts);
+ Brush *brush_old = paint->brush;
+ for (Brush *brush = bmain->brush.first; brush; brush = brush->id.next) {
+ if ((brush->ob_mode == OB_MODE_GPENCIL_PAINT) &&
+ (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE))
+ {
+ /* save first eraser to use later if no default */
+ if (brush_dft == NULL) {
+ brush_dft = brush;
+ }
+ /* found default */
+ if (brush->gpencil_settings->flag & GP_BRUSH_DEFAULT_ERASER) {
+ return brush;
+ }
+ }
+ }
+ /* if no default, but exist eraser brush, return this and set as default */
+ if (brush_dft) {
+ brush_dft->gpencil_settings->flag |= GP_BRUSH_DEFAULT_ERASER;
+ return brush_dft;
+ }
+ /* create a new soft eraser brush */
+ else {
+ brush_dft = BKE_brush_add_gpencil(bmain, ts, "Soft Eraser");
+ brush_dft->size = 30.0f;
+ brush_dft->gpencil_settings->flag |= (GP_BRUSH_ENABLE_CURSOR | GP_BRUSH_DEFAULT_ERASER);
+ brush_dft->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_SOFT;
+ brush_dft->gpencil_settings->brush_type = GP_BRUSH_TYPE_ERASE;
+ brush_dft->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_SOFT;
- palcolor = BKE_gpencil_palettecolor_addnew(palette, DATA_("Color"), true);
+ /* reset current brush */
+ BKE_paint_brush_set(paint, brush_old);
- return palcolor;
+ return brush_dft;
+ }
}
/* initialize a drawing brush */
-static void gp_init_drawing_brush(ToolSettings *ts, tGPsdata *p)
+static void gp_init_drawing_brush(bContext *C, tGPsdata *p)
{
- bGPDbrush *brush;
+ Brush *brush;
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+
+ Paint *paint = BKE_brush_get_gpencil_paint(ts);
/* if not exist, create a new one */
- if (BLI_listbase_is_empty(&ts->gp_brushes)) {
+ if (paint->brush == NULL) {
/* create new brushes */
- BKE_gpencil_brush_init_presets(ts);
- brush = BKE_gpencil_brush_getactive(ts);
+ BKE_brush_gpencil_presets(C);
+ brush = BKE_brush_getactive_gpencil(ts);
}
else {
/* Use the current */
- brush = BKE_gpencil_brush_getactive(ts);
+ brush = BKE_brush_getactive_gpencil(ts);
}
/* be sure curves are initializated */
- curvemapping_initialize(brush->cur_sensitivity);
- curvemapping_initialize(brush->cur_strength);
- curvemapping_initialize(brush->cur_jitter);
+ curvemapping_initialize(brush->gpencil_settings->curve_sensitivity);
+ curvemapping_initialize(brush->gpencil_settings->curve_strength);
+ curvemapping_initialize(brush->gpencil_settings->curve_jitter);
/* asign to temp tGPsdata */
p->brush = brush;
+ if (brush->gpencil_settings->brush_type != GP_BRUSH_TYPE_ERASE) {
+ p->eraser = gp_get_default_eraser(p->bmain, ts);
+ }
+ else {
+ p->eraser = brush;
+ }
+ /* use radius of eraser */
+ p->radius = (short)p->eraser->size;
+
+ /* GPXX: Need this update to synchronize brush with draw manager.
+ * Maybe this update can be removed when the new tool system
+ * will be in place, but while, we need this to keep drawing working.
+ *
+ */
+ DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
}
-/* initialize a paint palette brush and a default color if not exist */
-static void gp_init_palette(tGPsdata *p)
+/* initialize a paint brush and a default color if not exist */
+static void gp_init_colors(tGPsdata *p)
{
- bGPdata *gpd;
- bGPDpalette *palette;
- bGPDpalettecolor *palcolor;
+ bGPdata *gpd = p->gpd;
+ Brush *brush = p->brush;
- gpd = p->gpd;
+ Material *ma = NULL;
+ MaterialGPencilStyle *gp_style = NULL;
+
+ /* use brush material */
+ ma = BKE_gpencil_get_material_from_brush(brush);
+
+ /* if no brush defaults, get material and color info
+ * NOTE: Ensures that everything we need will exist...
+ */
+ if ((ma == NULL) || (ma->gp_style == NULL)) {
+ BKE_gpencil_material_ensure(p->bmain, p->ob);
- /* if not exist, create a new palette */
- if (BLI_listbase_is_empty(&gpd->palettes)) {
- /* create new palette */
- palette = BKE_gpencil_palette_addnew(gpd, DATA_("GP_Palette"), true);
- /* now create a default color */
- palcolor = gp_create_new_color(palette);
+ /* assign always the first material to the brush */
+ p->material = give_current_material(p->ob, 1);
+ brush->gpencil_settings->material = p->material;
}
else {
- /* Use the current palette and color */
- palette = BKE_gpencil_palette_getactive(gpd);
- /* the palette needs one color */
- if (BLI_listbase_is_empty(&palette->colors)) {
- palcolor = gp_create_new_color(palette);
- }
- else {
- palcolor = BKE_gpencil_palettecolor_getactive(palette);
- }
- /* in some situations can be null, so use first */
- if (palcolor == NULL) {
- BKE_gpencil_palettecolor_setactive(palette, palette->colors.first);
- palcolor = palette->colors.first;
- }
+ p->material = ma;
}
- /* asign to temp tGPsdata */
- p->palettecolor = palcolor;
+ /* check if the material is already on object material slots and add it if missing */
+ if (BKE_gpencil_get_material_index(p->ob, p->material) == 0) {
+ BKE_object_material_slot_add(p->bmain, p->ob);
+ assign_material(p->bmain, p->ob, ma, p->ob->totcol, BKE_MAT_ASSIGN_USERPREF);
+ }
+
+ /* assign color information to temp tGPsdata */
+ gp_style = p->material->gp_style;
+ if (gp_style) {
+
+ /* set colors */
+ copy_v4_v4(gpd->runtime.scolor, gp_style->stroke_rgba);
+ copy_v4_v4(gpd->runtime.sfill, gp_style->fill_rgba);
+ /* add some alpha to make easy the filling without hide strokes */
+ if (gpd->runtime.sfill[3] > 0.8f) {
+ gpd->runtime.sfill[3] = 0.8f;
+ }
+
+ gpd->runtime.mode = (short)gp_style->mode;
+ gpd->runtime.bstroke_style = gp_style->stroke_style;
+ gpd->runtime.bfill_style = gp_style->fill_style;
+ }
}
/* (re)init new painting data */
-static bool gp_session_initdata(bContext *C, tGPsdata *p)
+static bool gp_session_initdata(bContext *C, wmOperator *op, tGPsdata *p)
{
Main *bmain = CTX_data_main(C);
bGPdata **gpd_ptr = NULL;
ScrArea *curarea = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
ToolSettings *ts = CTX_data_tool_settings(C);
+ Object *obact = CTX_data_active_object(C);
+ View3D *v3d = curarea->spacedata.first;
/* make sure the active view (at the starting time) is a 3d-view */
if (curarea == NULL) {
@@ -1406,10 +1645,12 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
}
/* pass on current scene and window */
+ p->C = C;
p->bmain = CTX_data_main(C);
p->scene = CTX_data_scene(C);
p->depsgraph = CTX_data_depsgraph(C);
p->win = CTX_wm_window(C);
+ p->disable_fill = RNA_boolean_get(op->ptr, "disable_fill");
unit_m4(p->imat);
unit_m4(p->mat);
@@ -1424,7 +1665,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
/* set current area
* - must verify that region data is 3D-view (and not something else)
*/
- /* CAUTION: If this is the "toolbar", then this will change on the first stroke */
+ /* CAUTION: If this is the "toolbar", then this will change on the first stroke */
p->sa = curarea;
p->ar = ar;
p->align_flag = &ts->gpencil_v3d_align;
@@ -1435,92 +1676,19 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
printf("Error: 3D-View active region doesn't have any region data, so cannot be drawable\n");
return 0;
}
- break;
- }
- case SPACE_NODE:
- {
- /* SpaceNode *snode = curarea->spacedata.first; */
-
- /* set current area */
- p->sa = curarea;
- p->ar = ar;
- p->v2d = &ar->v2d;
- p->align_flag = &ts->gpencil_v2d_align;
- break;
- }
- case SPACE_SEQ:
- {
- SpaceSeq *sseq = curarea->spacedata.first;
-
- /* set current area */
- p->sa = curarea;
- p->ar = ar;
- p->v2d = &ar->v2d;
- p->align_flag = &ts->gpencil_seq_align;
- /* check that gpencil data is allowed to be drawn */
- if (sseq->mainb == SEQ_DRAW_SEQUENCE) {
- p->status = GP_STATUS_ERROR;
- if (G.debug & G_DEBUG)
- printf("Error: In active view (sequencer), active mode doesn't support Grease Pencil\n");
- return 0;
+ /* if active object doesn't exist or isn't a GP Object, create one */
+ float *cur = ED_view3d_cursor3d_get(p->scene, v3d)->location;
+ if ((!obact) || (obact->type != OB_GPENCIL)) {
+ /* create new default object */
+ obact = ED_add_gpencil_object(C, p->scene, cur);
}
- break;
- }
- case SPACE_IMAGE:
- {
- /* SpaceImage *sima = curarea->spacedata.first; */
+ /* assign object after all checks to be sure we have one active */
+ p->ob = obact;
- /* set the current area */
- p->sa = curarea;
- p->ar = ar;
- p->v2d = &ar->v2d;
- p->align_flag = &ts->gpencil_ima_align;
break;
}
- case SPACE_CLIP:
- {
- SpaceClip *sc = curarea->spacedata.first;
- MovieClip *clip = ED_space_clip_get_clip(sc);
-
- if (clip == NULL) {
- p->status = GP_STATUS_ERROR;
- return false;
- }
-
- /* set the current area */
- p->sa = curarea;
- p->ar = ar;
- p->v2d = &ar->v2d;
- p->align_flag = &ts->gpencil_v2d_align;
-
- invert_m4_m4(p->imat, sc->unistabmat);
-
- /* custom color for new layer */
- p->custom_color[0] = 1.0f;
- p->custom_color[1] = 0.0f;
- p->custom_color[2] = 0.5f;
- p->custom_color[3] = 0.9f;
-
- if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
- int framenr = ED_space_clip_get_clip_frame_number(sc);
- MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
- MovieTrackingMarker *marker = track ? BKE_tracking_marker_get(track, framenr) : NULL;
-
- if (marker) {
- p->imat[3][0] -= marker->pos[0];
- p->imat[3][1] -= marker->pos[1];
- }
- else {
- p->status = GP_STATUS_ERROR;
- return false;
- }
- }
- invert_m4_m4(p->mat, p->imat);
- copy_m4_m4(p->gsc.mat, p->mat);
- break;
- }
/* unsupported views */
default:
{
@@ -1533,7 +1701,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
/* get gp-data */
gpd_ptr = ED_gpencil_data_get_pointers(C, &p->ownerPtr);
- if (gpd_ptr == NULL) {
+ if ((gpd_ptr == NULL) || ED_gpencil_data_owner_is_annotation(&p->ownerPtr)) {
p->status = GP_STATUS_ERROR;
if (G.debug & G_DEBUG)
printf("Error: Current context doesn't allow for any Grease Pencil data\n");
@@ -1555,16 +1723,18 @@ 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);
+
/* set brush and create a new one if null */
- gp_init_drawing_brush(ts, p);
- /* set palette info and create a new one if null */
- gp_init_palette(p);
- /* set palette colors */
- bGPDpalettecolor *palcolor = p->palettecolor;
- bGPdata *pdata = p->gpd;
- copy_v4_v4(pdata->scolor, palcolor->color);
- copy_v4_v4(pdata->sfill, palcolor->fill);
- pdata->sflag = palcolor->flag;
+ gp_init_drawing_brush(C, p);
+
+ /* setup active color */
+ if (curarea->spacetype == SPACE_VIEW3D) {
+ /* NOTE: This is only done for 3D view, as Materials aren't used for
+ * annotations in 2D editors
+ */
+ gp_init_colors(p);
+ }
+
/* lock axis */
p->lock_axis = ts->gp_sculpt.lock_axis;
@@ -1572,20 +1742,24 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
}
/* init new painting session */
-static tGPsdata *gp_session_initpaint(bContext *C)
+static tGPsdata *gp_session_initpaint(bContext *C, wmOperator *op)
{
tGPsdata *p = NULL;
- /* create new context data */
+ /* Create new context data */
p = MEM_callocN(sizeof(tGPsdata), "GPencil Drawing Data");
- gp_session_initdata(C, p);
-
- /* radius for eraser circle is defined in userprefs now */
- /* NOTE: we do this here, so that if we exit immediately,
- * erase size won't get lost
+ /* Try to initialise context data
+ * WARNING: This may not always succeed (e.g. using GP in an annotation-only context)
*/
- p->radius = U.gp_eraser;
+ if (gp_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.
+ */
+ MEM_freeN(p);
+ return NULL;
+ }
/* Random generator, only init once. */
uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX);
@@ -1606,15 +1780,15 @@ static void gp_session_cleanup(tGPsdata *p)
return;
/* free stroke buffer */
- if (gpd->sbuffer) {
+ if (gpd->runtime.sbuffer) {
/* printf("\t\tGP - free sbuffer\n"); */
- MEM_freeN(gpd->sbuffer);
- gpd->sbuffer = NULL;
+ MEM_freeN(gpd->runtime.sbuffer);
+ gpd->runtime.sbuffer = NULL;
}
/* clear flags */
- gpd->sbuffer_size = 0;
- gpd->sbuffer_sflag = 0;
+ gpd->runtime.sbuffer_size = 0;
+ gpd->runtime.sbuffer_sflag = 0;
p->inittime = 0.0;
}
@@ -1632,11 +1806,12 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
{
Scene *scene = p->scene;
ToolSettings *ts = scene->toolsettings;
+ int cfra_eval = (int)DEG_get_ctime(p->depsgraph);
/* get active layer (or add a new one if non-existent) */
p->gpl = BKE_gpencil_layer_getactive(p->gpd);
if (p->gpl == NULL) {
- p->gpl = BKE_gpencil_layer_addnew(p->gpd, "GP_Layer", true);
+ p->gpl = BKE_gpencil_layer_addnew(p->gpd, DATA_("GP_Layer"), true);
if (p->custom_color[3])
copy_v3_v3(p->gpl->color, p->custom_color);
@@ -1670,7 +1845,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
* -> If there are no strokes in that frame, don't add a new empty frame
*/
if (gpl->actframe && gpl->actframe->strokes.first) {
- gpl->actframe = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_COPY);
+ gpl->actframe = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_ADD_COPY);
has_layer_to_erase = true;
}
@@ -1708,7 +1883,9 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
else
add_frame_mode = GP_GETFRAME_ADD_NEW;
- p->gpf = BKE_gpencil_layer_getframe(p->gpl, CFRA, add_frame_mode);
+ p->gpf = BKE_gpencil_layer_getframe(p->gpl, cfra_eval, add_frame_mode);
+ /* set as dirty draw manager cache */
+ gp_update_cache(p->gpd);
if (p->gpf == NULL) {
p->status = GP_STATUS_ERROR;
@@ -1724,7 +1901,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
/* set 'eraser' for this stroke if using eraser */
p->paintmode = paintmode;
if (p->paintmode == GP_PAINTMODE_ERASER) {
- p->gpd->sbuffer_sflag |= GP_STROKE_ERASER;
+ p->gpd->runtime.sbuffer_sflag |= GP_STROKE_ERASER;
/* check if we should respect depth while erasing */
if (p->sa->spacetype == SPACE_VIEW3D) {
@@ -1735,7 +1912,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
}
else {
/* disable eraser flags - so that we can switch modes during a session */
- p->gpd->sbuffer_sflag &= ~GP_STROKE_ERASER;
+ p->gpd->runtime.sbuffer_sflag &= ~GP_STROKE_ERASER;
if (p->sa->spacetype == SPACE_VIEW3D) {
if (p->gpl->flag & GP_LAYER_NO_XRAY) {
@@ -1744,10 +1921,16 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
}
}
+ /* set special fill stroke mode */
+ if (p->disable_fill == true) {
+ p->gpd->runtime.sbuffer_sflag |= GP_STROKE_NOFILL;
+ /* replace stroke color with fill color */
+ copy_v4_v4(p->gpd->runtime.scolor, p->gpd->runtime.sfill);
+ }
+
/* set 'initial run' flag, which is only used to denote when a new stroke is starting */
p->flags |= GP_PAINTFLAG_FIRSTRUN;
-
/* when drawing in the camera view, in 2D space, set the subrect */
p->subrect = NULL;
if ((*p->align_flag & GP_PROJECT_VIEWSPACE) == 0) {
@@ -1782,41 +1965,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
switch (p->sa->spacetype) {
case SPACE_VIEW3D:
{
- p->gpd->sbuffer_sflag |= GP_STROKE_3DSPACE;
- break;
- }
- case SPACE_NODE:
- {
- p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE;
- break;
- }
- case SPACE_SEQ:
- {
- p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE;
- break;
- }
- case SPACE_IMAGE:
- {
- SpaceImage *sima = (SpaceImage *)p->sa->spacedata.first;
-
- /* only set these flags if the image editor doesn't have an image active,
- * otherwise user will be confused by strokes not appearing after they're drawn
- *
- * Admittedly, this is a bit hacky, but it works much nicer from an ergonomic standpoint!
- */
- if (ELEM(NULL, sima, sima->image)) {
- /* make strokes be drawn in screen space */
- p->gpd->sbuffer_sflag &= ~GP_STROKE_2DSPACE;
- *(p->align_flag) &= ~GP_PROJECT_VIEWSPACE;
- }
- else {
- p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE;
- }
- break;
- }
- case SPACE_CLIP:
- {
- p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE;
+ p->gpd->runtime.sbuffer_sflag |= GP_STROKE_3DSPACE;
break;
}
}
@@ -1839,7 +1988,7 @@ static void gp_paint_strokeend(tGPsdata *p)
}
/* check if doing eraser or not */
- if ((p->gpd->sbuffer_sflag & GP_STROKE_ERASER) == 0) {
+ if ((p->gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) {
/* simplify stroke before transferring? */
gp_stroke_simplify(p);
@@ -1875,8 +2024,8 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr)
tGPsdata *p = (tGPsdata *)p_ptr;
if (p->paintmode == GP_PAINTMODE_ERASER) {
- Gwn_VertFormat *format = immVertexFormat();
- const uint shdr_pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ const uint shdr_pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
GPU_line_smooth(true);
@@ -1920,10 +2069,12 @@ static void gpencil_draw_toggle_eraser_cursor(bContext *C, tGPsdata *p, short en
p->erasercursor = NULL;
}
else if (enable && !p->erasercursor) {
+ ED_gpencil_toggle_brush_cursor(p->C, false, NULL);
/* enable cursor */
- p->erasercursor = WM_paint_cursor_activate(CTX_wm_manager(C),
- NULL, /* XXX */
- gpencil_draw_eraser, p);
+ p->erasercursor = WM_paint_cursor_activate(
+ CTX_wm_manager(C),
+ NULL, /* XXX */
+ gpencil_draw_eraser, p);
}
}
@@ -1944,12 +2095,6 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op)
{
tGPsdata *p = op->customdata;
- /* clear undo stack */
- gpencil_undo_finish();
-
- /* restore cursor to indicate end of drawing */
- WM_cursor_modal_restore(CTX_wm_window(C));
-
/* don't assume that operator data exists at all */
if (p) {
/* check size of buffer before cleanup, to determine if anything happened here */
@@ -1962,12 +2107,38 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op)
* NOTE: Do this even when not in eraser mode, as eraser may
* have been toggled at some point.
*/
- U.gp_eraser = p->radius;
+ if (p->eraser) {
+ p->eraser->size = p->radius;
+ }
+
+ /* restore cursor to indicate end of drawing */
+ if (p->sa->spacetype != SPACE_VIEW3D) {
+ WM_cursor_modal_restore(CTX_wm_window(C));
+ }
+ else {
+ /* or restore paint if 3D view */
+ if ((p) && (p->paintmode == GP_PAINTMODE_ERASER)) {
+ WM_cursor_modal_set(p->win, CURSOR_STD);
+ }
+
+ /* drawing batch cache is dirty now */
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ if (gpd) {
+ gp_update_cache(gpd);
+ }
+ }
+
+ /* clear undo stack */
+ gpencil_undo_finish();
/* cleanup */
gp_paint_cleanup(p);
gp_session_cleanup(p);
+ ED_gpencil_toggle_brush_cursor(C, true, NULL);
+
+ /* finally, free the temp data */
gp_session_free(p);
+ p = NULL;
}
op->customdata = NULL;
@@ -1986,9 +2157,18 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p;
eGPencil_PaintModes paintmode = RNA_enum_get(op->ptr, "mode");
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Brush *brush = BKE_brush_getactive_gpencil(ts);
+
+ /* if mode is draw and the brush is eraser, cancel */
+ if (paintmode != GP_PAINTMODE_ERASER) {
+ if ((brush) && (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) {
+ return 0;
+ }
+ }
/* check context */
- p = op->customdata = gp_session_initpaint(C);
+ p = op->customdata = gp_session_initpaint(C, op);
if ((p == NULL) || (p->status == GP_STATUS_ERROR)) {
/* something wasn't set correctly in context */
gpencil_draw_exit(C, op);
@@ -2009,6 +2189,8 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
p->keymodifier = -1;
}
+ p->reports = op->reports;
+
/* everything is now setup ok */
return 1;
}
@@ -2019,10 +2201,15 @@ 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)
{
- if (p->paintmode == GP_PAINTMODE_ERASER)
+ Brush *brush = p->brush;
+ if ((p->paintmode == GP_PAINTMODE_ERASER) ||
+ (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE))
+ {
WM_cursor_modal_set(p->win, BC_CROSSCURSOR); /* XXX need a better cursor */
- else
- WM_cursor_modal_set(p->win, BC_PAINTBRUSHCURSOR);
+ }
+ else {
+ WM_cursor_modal_set(p->win, CURSOR_STD);
+ }
}
/* update UI indicators of status, including cursor and header prints */
@@ -2030,11 +2217,24 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p)
{
/* header prints */
switch (p->status) {
- case GP_STATUS_PAINTING:
- /* only print this for paint-sessions, otherwise it gets annoying */
- if (GPENCIL_SKETCH_SESSIONS_ON(p->scene))
- ED_workspace_status_text(C, IFACE_("Grease Pencil: Drawing/erasing stroke... Release to end stroke"));
- break;
+
+#if 0 /* FIXME, this never runs! */
+ switch (p->paintmode) {
+ case GP_PAINTMODE_DRAW_POLY:
+ /* Provide usage tips, since this is modal, and unintuitive without hints */
+ ED_workspace_status_text(
+ C, IFACE_(
+ "Annotation Create Poly: LMB click to place next stroke vertex | "
+ "ESC/Enter to end (or click outside this area)"
+ ));
+ break;
+ default:
+ /* Do nothing - the others are self explanatory, exit quickly once the mouse is released
+ * Showing any text would just be annoying as it would flicker.
+ */
+ break;
+ }
+#endif
case GP_STATUS_IDLING:
/* print status info */
@@ -2048,12 +2248,11 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p)
"ESC/Enter to end (or click outside this area)"));
break;
case GP_PAINTMODE_DRAW:
- ED_workspace_status_text(C, IFACE_("Grease Pencil Freehand Session: Hold and drag LMB to draw | "
- "E/ESC/Enter to end (or click outside this area)"));
+ ED_workspace_status_text(C, IFACE_("Grease Pencil Freehand Session: Hold and drag LMB to draw"));
break;
case GP_PAINTMODE_DRAW_POLY:
ED_workspace_status_text(C, IFACE_("Grease Pencil Poly Session: LMB click to place next stroke vertex | "
- "ESC/Enter to end (or click outside this area)"));
+ "Release Shift/ESC/Enter to end (or click outside this area)"));
break;
default: /* unhandled future cases */
@@ -2067,14 +2266,19 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p)
/* clear status string */
ED_workspace_status_text(C, NULL);
break;
+ case GP_STATUS_PAINTING:
+ break;
}
}
/* ------------------------------- */
/* 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 gpencil_draw_apply(bContext *C, wmOperator *op, tGPsdata *p, Depsgraph *depsgraph)
{
+ bGPdata *gpd = p->gpd;
+ tGPspoint *pt = NULL;
+
/* handle drawing/erasing -> test for erasing first */
if (p->paintmode == GP_PAINTMODE_ERASER) {
/* do 'live' erasing now */
@@ -2087,6 +2291,17 @@ 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)) {
+
+ /* if lazy mouse, interpolate the last and current mouse positions */
+ if (GPENCIL_LAZY_MODE(p->brush, p->shift)) {
+ float now_mouse[2];
+ float last_mouse[2];
+ copy_v2fl_v2i(now_mouse, p->mval);
+ copy_v2fl_v2i(last_mouse, p->mvalo);
+ interp_v2_v2v2(now_mouse, now_mouse, last_mouse, p->brush->smooth_stroke_factor);
+ round_v2i_v2fl(p->mval, now_mouse);
+ }
+
/* try to add point */
short ok = gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
@@ -2124,11 +2339,24 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph
p->mvalo[1] = p->mval[1];
p->opressure = p->pressure;
p->ocurtime = p->curtime;
+
+ pt = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_size - 1;
+ if (p->paintmode != GP_PAINTMODE_ERASER) {
+ ED_gpencil_toggle_brush_cursor(C, true, &pt->x);
+ }
+ }
+ else if ((p->brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) &&
+ (gpd->runtime.sbuffer_size > 0))
+ {
+ pt = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_size - 1;
+ if (p->paintmode != GP_PAINTMODE_ERASER) {
+ ED_gpencil_toggle_brush_cursor(C, true, &pt->x);
+ }
}
}
/* handle draw event */
-static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsgraph *depsgraph)
+static void gpencil_draw_apply_event(bContext *C, wmOperator *op, const wmEvent *event, Depsgraph *depsgraph, int x, int y)
{
tGPsdata *p = op->customdata;
PointerRNA itemptr;
@@ -2136,13 +2364,15 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg
int tablet = 0;
/* convert from window-space to area-space mouse coordinates
+ * add any x,y override position for fake events
* NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding...
*/
- p->mval[0] = event->mval[0] + 1;
- p->mval[1] = event->mval[1] + 1;
+ p->mval[0] = event->mval[0] + 1 - x;
+ p->mval[1] = event->mval[1] + 1 - y;
+ p->shift = event->shift;
/* verify key status for straight lines */
- if ((event->ctrl > 0) || (event->alt > 0)) {
+ if ((event->alt > 0) && (RNA_boolean_get(op->ptr, "disable_straight") == false)) {
if (p->straight[0] == 0) {
int dx = abs(p->mval[0] - p->mvalo[0]);
int dy = abs(p->mval[1] - p->mvalo[1]);
@@ -2151,12 +2381,12 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg
if (dx >= dy) {
/* horizontal */
p->straight[0] = 1;
- p->straight[1] = p->mval[1]; /* save y */
+ p->straight[1] = (short)p->mval[1]; /* save y */
}
else {
/* vertical */
p->straight[0] = 2;
- p->straight[1] = p->mval[0]; /* save x */
+ p->straight[1] = (short)p->mval[0]; /* save x */
}
}
}
@@ -2191,6 +2421,22 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg
p->pressure = 1.0f;
}
+ /* special eraser modes */
+ if (p->paintmode == GP_PAINTMODE_ERASER) {
+ if (event->shift > 0) {
+ p->flags |= GP_PAINTFLAG_HARD_ERASER;
+ }
+ else {
+ p->flags &= ~GP_PAINTFLAG_HARD_ERASER;
+ }
+ if (event->alt > 0) {
+ p->flags |= GP_PAINTFLAG_STROKE_ERASER;
+ }
+ else {
+ p->flags &= ~GP_PAINTFLAG_STROKE_ERASER;
+ }
+ }
+
/* special exception for start of strokes (i.e. maybe for just a dot) */
if (p->flags & GP_PAINTFLAG_FIRSTRUN) {
p->flags &= ~GP_PAINTFLAG_FIRSTRUN;
@@ -2233,7 +2479,7 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg
RNA_float_set(&itemptr, "time", p->curtime - p->inittime);
/* apply the current latest drawing point */
- gpencil_draw_apply(op, p, depsgraph);
+ gpencil_draw_apply(C, op, p, depsgraph);
/* force refresh */
ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */
@@ -2251,7 +2497,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
/* try to initialize context data needed while drawing */
if (!gpencil_draw_init(C, op, NULL)) {
- if (op->customdata) MEM_freeN(op->customdata);
+ MEM_SAFE_FREE(op->customdata);
/* printf("\tGP - no valid data\n"); */
return OPERATOR_CANCELLED;
}
@@ -2298,7 +2544,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
}
/* apply this data as necessary now (as per usual) */
- gpencil_draw_apply(op, p, depsgraph);
+ gpencil_draw_apply(C, op, p, depsgraph);
}
RNA_END;
@@ -2324,6 +2570,11 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
if (G.debug & G_DEBUG)
printf("GPencil - Starting Drawing\n");
+ /* support for tablets eraser pen */
+ if (gpencil_is_tablet_eraser_active(event)) {
+ RNA_enum_set(op->ptr, "mode", GP_PAINTMODE_ERASER);
+ }
+
/* try to initialize context data needed while drawing */
if (!gpencil_draw_init(C, op, event)) {
if (op->customdata)
@@ -2344,6 +2595,9 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
if (p->paintmode == GP_PAINTMODE_ERASER) {
gpencil_draw_toggle_eraser_cursor(C, p, true);
}
+ else {
+ ED_gpencil_toggle_brush_cursor(C, true, NULL);
+ }
/* set cursor
* NOTE: This may change later (i.e. intentionally via brush toggle,
* or unintentionally if the user scrolls outside the area)...
@@ -2357,7 +2611,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
p->status = GP_STATUS_PAINTING;
/* handle the initial drawing - i.e. for just doing a simple dot */
- gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C));
+ gpencil_draw_apply_event(C, op, event, CTX_data_depsgraph(C), 0, 0);
op->flag |= OP_IS_MODAL_CURSOR_REGION;
}
else {
@@ -2366,9 +2620,29 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
op->flag |= OP_IS_MODAL_CURSOR_REGION;
}
+ /* enable paint mode */
+ if (p->sa->spacetype == SPACE_VIEW3D) {
+ Object *ob = CTX_data_active_object(C);
+ if (ob && (ob->type == OB_GPENCIL) && ((p->gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0)) {
+ /* Just set paintmode flag... */
+ p->gpd->flag |= GP_DATA_STROKE_PAINTMODE;
+ /* disable other GP modes */
+ p->gpd->flag &= ~GP_DATA_STROKE_EDITMODE;
+ p->gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE;
+ p->gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE;
+ /* set workspace mode */
+ ob->restore_mode = ob->mode;
+ ob->mode = OB_MODE_GPENCIL_PAINT;
+ /* redraw mode on screen */
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);
+ }
+ }
+
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+
/* add a modal handler for this operator, so that we can then draw continuous strokes */
WM_event_add_modal_handler(C, op);
+
return OPERATOR_RUNNING_MODAL;
}
@@ -2397,7 +2671,7 @@ 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))
+ if (gp_session_initdata(C, op, p))
gp_paint_initstroke(p, p->paintmode, CTX_data_depsgraph(C));
if (p->status != GP_STATUS_ERROR) {
@@ -2448,6 +2722,76 @@ static void gpencil_move_last_stroke_to_back(bContext *C)
BLI_insertlinkbefore(&gpf->strokes, gpf->strokes.first, gps);
}
+/* add events for missing mouse movements when the artist draw very fast */
+static void gpencil_add_missing_events(bContext *C, wmOperator *op, const wmEvent *event, tGPsdata *p)
+{
+ Brush *brush = p->brush;
+ if (brush->gpencil_settings->input_samples == 0) {
+ return;
+ }
+ RegionView3D *rv3d = p->ar->regiondata;
+ float defaultpixsize = rv3d->pixsize * 1000.0f;
+ int samples = (GP_MAX_INPUT_SAMPLES - brush->gpencil_settings->input_samples + 1);
+ float thickness = (float)brush->size;
+
+ float pt[2], a[2], b[2];
+ float vec[3];
+ float scale = 1.0f;
+
+ /* get pixel scale */
+ gp_get_3d_reference(p, vec);
+ mul_m4_v3(rv3d->persmat, vec);
+ if (rv3d->is_persp) {
+ scale = vec[2] * defaultpixsize;
+ }
+ else {
+ scale = defaultpixsize;
+ }
+
+ /* The thickness of the brush is reduced of thickness to get overlap dots */
+ float dot_factor = 0.50f;
+ if (samples < 2) {
+ dot_factor = 0.05f;
+ }
+ else if (samples < 4) {
+ dot_factor = 0.10f;
+ }
+ else if (samples < 7) {
+ dot_factor = 0.3f;
+ }
+ else if (samples < 10) {
+ dot_factor = 0.4f;
+ }
+ float factor = ((thickness * dot_factor) / scale) * samples;
+
+ copy_v2fl_v2i(a, p->mvalo);
+ b[0] = event->mval[0] + 1;
+ b[1] = event->mval[1] + 1;
+
+ /* get distance in pixels */
+ float dist = len_v2v2(a, b);
+
+ /* for very small distances, add a half way point */
+ if (dist <= 2.0f) {
+ interp_v2_v2v2(pt, a, b, 0.5f);
+ sub_v2_v2v2(pt, b, pt);
+ /* create fake event */
+ gpencil_draw_apply_event(C, op, event, CTX_data_depsgraph(C),
+ (int)pt[0], (int)pt[1]);
+ }
+ else if (dist >= factor) {
+ int slices = 2 + (int)((dist - 1.0) / factor);
+ float n = 1.0f / slices;
+ for (int i = 1; i < slices; i++) {
+ interp_v2_v2v2(pt, a, b, n * i);
+ sub_v2_v2v2(pt, b, pt);
+ /* create fake event */
+ gpencil_draw_apply_event(C, op, event, CTX_data_depsgraph(C),
+ (int)pt[0], (int)pt[1]);
+ }
+ }
+}
+
/* events handling during interactive drawing part of operator */
static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
@@ -2488,10 +2832,6 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
* is essential for ensuring that they can quickly return to that view
*/
}
- else if ((ELEM(event->type, p->keymodifier)) && (event->val == KM_RELEASE)) {
- /* enable continuous if release D key in mid drawing */
- p->scene->toolsettings->gpencil_flags |= GP_TOOL_FLAG_PAINTSESSIONS_ON;
- }
else if ((event->type == BKEY) && (event->val == KM_RELEASE)) {
/* Add Blank Frame
* - Since this operator is non-modal, we can just call it here, and keep going...
@@ -2510,7 +2850,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* exit painting mode (and/or end current stroke)
* NOTE: cannot do RIGHTMOUSE (as is standard for canceling) as that would break polyline [#32647]
*/
- if (ELEM(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY, EKEY)) {
+ /* if polyline and release shift must cancel */
+ if ((ELEM(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY, EKEY)) ||
+ ((p->paintmode == GP_PAINTMODE_DRAW_POLY) && (event->shift == 0)))
+ {
/* exit() ends the current stroke before cleaning up */
/* printf("\t\tGP - end of paint op + end of stroke\n"); */
/* if drawing polygon and enable on back, must move stroke */
@@ -2537,10 +2880,8 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
int sketch = 0;
/* basically, this should be mouse-button up = end stroke
- * BUT what happens next depends on whether we 'painting sessions' is enabled
+ * BUT, polyline drawing is an exception -- all knots should be added during one session
*/
- sketch |= GPENCIL_SKETCH_SESSIONS_ON(p->scene);
- /* polyline drawing is also 'sketching' -- all knots should be added during one session */
sketch |= (p->paintmode == GP_PAINTMODE_DRAW_POLY);
if (sketch) {
@@ -2585,6 +2926,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
}
+ /* drawing batch cache is dirty now */
+ gp_update_cache(p->gpd);
+
p->status = GP_STATUS_DONE;
estate = OPERATOR_FINISHED;
}
@@ -2689,7 +3033,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || (p->flags & GP_PAINTFLAG_FIRSTRUN)) {
/* handle drawing event */
/* printf("\t\tGP - add point\n"); */
- gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C));
+ gpencil_add_missing_events(C, op, event, p);
+
+ gpencil_draw_apply_event(C, op, event, CTX_data_depsgraph(C), 0, 0);
/* finish painting operation if anything went wrong just now */
if (p->status == GP_STATUS_ERROR) {
@@ -2791,7 +3137,7 @@ void GPENCIL_OT_draw(wmOperatorType *ot)
/* identifiers */
ot->name = "Grease Pencil Draw";
ot->idname = "GPENCIL_OT_draw";
- ot->description = "Make annotations on the active data";
+ ot->description = "Draw a new stroke in the active Grease Pencil Object";
/* api callbacks */
ot->exec = gpencil_draw_exec;
@@ -2811,5 +3157,11 @@ void GPENCIL_OT_draw(wmOperatorType *ot)
/* NOTE: wait for input is enabled by default, so that all UI code can work properly without needing users to know about this */
prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "Wait for first click instead of painting immediately");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(ot->srna, "disable_straight", false, "No Straight lines", "Disable key for straight lines");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(ot->srna, "disable_fill", false, "No Fill Areas", "Disable fill to use stroke as fill boundary");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
new file mode 100644
index 00000000000..2dfdeeba0b6
--- /dev/null
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -0,0 +1,716 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2017, Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Antonio Vazquez
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Operators for creating new Grease Pencil primitives (boxes, circles, ...)
+ */
+
+/** \file blender/editors/gpencil/gpencil_primitive.c
+ * \ingroup edgpencil
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "BLT_translation.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_meshdata_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 "BKE_main.h"
+#include "BKE_brush.h"
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_gpencil.h"
+#include "BKE_library.h"
+#include "BKE_material.h"
+#include "BKE_paint.h"
+#include "BKE_report.h"
+
+#include "UI_interface.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "ED_gpencil.h"
+#include "ED_object.h"
+#include "ED_screen.h"
+#include "ED_view3d.h"
+#include "ED_space_api.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "gpencil_intern.h"
+
+#define MIN_EDGES 2
+#define MAX_EDGES 100
+
+#define IDLE 0
+#define IN_PROGRESS 1
+
+/* ************************************************ */
+/* Core/Shared Utilities */
+
+/* Poll callback for primitive operators */
+static bool gpencil_primitive_add_poll(bContext *C)
+{
+ /* only 3D view */
+ ScrArea *sa = CTX_wm_area(C);
+ if (sa && sa->spacetype != SPACE_VIEW3D) {
+ return 0;
+ }
+
+ /* need data to create primitive */
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ if (gpd == NULL) {
+ return 0;
+ }
+
+ /* only in edit and paint modes
+ * - paint as it's the "drawing/creation mode"
+ * - edit as this is more of an atomic editing operation
+ * (similar to copy/paste), and also for consistency
+ */
+ if ((gpd->flag & (GP_DATA_STROKE_PAINTMODE | GP_DATA_STROKE_EDITMODE)) == 0) {
+ CTX_wm_operator_poll_msg_set(C, "Primitives can only be added in Draw or Edit modes");
+ return 0;
+ }
+
+ /* don't allow operator to function if the active layer is locked/hidden
+ * (BUT, if there isn't an active layer, we are free to add new layer when the time comes)
+ */
+ bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
+ if ((gpl) && (gpl->flag & (GP_LAYER_LOCKED | GP_LAYER_HIDE))) {
+ CTX_wm_operator_poll_msg_set(C, "Primitives cannot be added as active layer is locked or hidden");
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/* ****************** Primitive Interactive *********************** */
+
+/* Helper: Create internal strokes primitives data */
+static void gp_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
+{
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
+ bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
+ Brush *brush;
+
+ /* if brush doesn't exist, create a new one */
+ Paint *paint = BKE_brush_get_gpencil_paint(ts);
+ /* if not exist, create a new one */
+ if (paint->brush == NULL) {
+ /* create new brushes */
+ BKE_brush_gpencil_presets(C);
+ brush = BKE_brush_getactive_gpencil(ts);
+ }
+ else {
+ /* Use the current */
+ brush = BKE_brush_getactive_gpencil(ts);
+ }
+ tgpi->brush = brush;
+
+ /* if layer doesn't exist, create a new one */
+ if (gpl == NULL) {
+ gpl = BKE_gpencil_layer_addnew(tgpi->gpd, DATA_("Primitives"), true);
+ }
+ tgpi->gpl = gpl;
+
+ /* create a new temporary frame */
+ tgpi->gpf = MEM_callocN(sizeof(bGPDframe), "Temp bGPDframe");
+ tgpi->gpf->framenum = tgpi->cframe = cfra_eval;
+
+ /* create new temp stroke */
+ bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "Temp bGPDstroke");
+ gps->thickness = 2.0f;
+ gps->inittime = 0.0f;
+
+ /* enable recalculation flag by default */
+ gps->flag |= GP_STROKE_RECALC_CACHES;
+ /* the polygon must be closed, so enabled cyclic */
+ gps->flag |= GP_STROKE_CYCLIC;
+ gps->flag |= GP_STROKE_3DSPACE;
+
+ gps->mat_nr = BKE_gpencil_get_material_index(tgpi->ob, tgpi->mat) - 1;
+
+ /* allocate memory for storage points, but keep empty */
+ gps->totpoints = 0;
+ gps->points = MEM_callocN(sizeof(bGPDspoint), "gp_stroke_points");
+ gps->dvert = MEM_callocN(sizeof(MDeformVert), "gp_stroke_weights");
+ /* initialize triangle memory to dummy data */
+ gps->tot_triangles = 0;
+ gps->triangles = NULL;
+ gps->flag |= GP_STROKE_RECALC_CACHES;
+
+ /* add to strokes */
+ BLI_addtail(&tgpi->gpf->strokes, gps);
+}
+
+/* ----------------------- */
+/* Drawing Callbacks */
+
+/* Drawing callback for modal operator in 3d mode */
+static void gpencil_primitive_draw_3d(const bContext *C, ARegion *UNUSED(ar), void *arg)
+{
+ tGPDprimitive *tgpi = (tGPDprimitive *)arg;
+ ED_gp_draw_primitives(C, tgpi, REGION_DRAW_POST_VIEW);
+}
+
+/* ----------------------- */
+
+/* Helper: Draw status message while the user is running the operator */
+static void gpencil_primitive_status_indicators(bContext *C, tGPDprimitive *tgpi)
+{
+ Scene *scene = tgpi->scene;
+ char status_str[UI_MAX_DRAW_STR];
+ char msg_str[UI_MAX_DRAW_STR];
+
+ if (tgpi->type == GP_STROKE_BOX) {
+ BLI_strncpy(msg_str, IFACE_("Rectangle: ESC/RMB to cancel, LMB set origin, Enter/LMB to confirm, Shift to square"), UI_MAX_DRAW_STR);
+ }
+ else if (tgpi->type == GP_STROKE_LINE) {
+ BLI_strncpy(msg_str, IFACE_("Line: ESC/RMB to cancel, LMB set origin, Enter/LMB to confirm"), UI_MAX_DRAW_STR);
+ }
+ else {
+ BLI_strncpy(msg_str, IFACE_("Circle: ESC/RMB to cancel, Enter/LMB to confirm, WHEEL to adjust edge number, Shift to square"), UI_MAX_DRAW_STR);
+ }
+
+ if (tgpi->type == GP_STROKE_CIRCLE) {
+ if (hasNumInput(&tgpi->num)) {
+ char str_offs[NUM_STR_REP_LEN];
+
+ outputNumInput(&tgpi->num, str_offs, &scene->unit);
+ BLI_snprintf(status_str, sizeof(status_str), "%s: %s", msg_str, str_offs);
+ }
+ else {
+ if (tgpi->flag == IN_PROGRESS) {
+ BLI_snprintf(
+ status_str, sizeof(status_str), "%s: %d (%d, %d) (%d, %d)", msg_str, (int)tgpi->tot_edges,
+ tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]);
+ }
+ else {
+ BLI_snprintf(
+ status_str, sizeof(status_str), "%s: %d (%d, %d)", msg_str, (int)tgpi->tot_edges,
+ tgpi->bottom[0], tgpi->bottom[1]);
+ }
+ }
+ }
+ else {
+ if (tgpi->flag == IN_PROGRESS) {
+ BLI_snprintf(
+ status_str, sizeof(status_str), "%s: (%d, %d) (%d, %d)", msg_str,
+ tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]);
+ }
+ else {
+ BLI_snprintf(
+ status_str, sizeof(status_str), "%s: (%d, %d)", msg_str,
+ tgpi->bottom[0], tgpi->bottom[1]);
+ }
+ }
+ ED_workspace_status_text(C, status_str);
+}
+
+/* ----------------------- */
+
+/* create a rectangle */
+static void gp_primitive_rectangle(tGPDprimitive *tgpi, tGPspoint *points2D)
+{
+ BLI_assert(tgpi->tot_edges == 4);
+
+ points2D[0].x = tgpi->top[0];
+ points2D[0].y = tgpi->top[1];
+
+ points2D[1].x = tgpi->bottom[0];
+ points2D[1].y = tgpi->top[1];
+
+ points2D[2].x = tgpi->bottom[0];
+ points2D[2].y = tgpi->bottom[1];
+
+ points2D[3].x = tgpi->top[0];
+ points2D[3].y = tgpi->bottom[1];
+}
+
+/* create a line */
+static void gp_primitive_line(tGPDprimitive *tgpi, tGPspoint *points2D)
+{
+ BLI_assert(tgpi->tot_edges == 2);
+
+ points2D[0].x = tgpi->top[0];
+ points2D[0].y = tgpi->top[1];
+
+ points2D[1].x = tgpi->bottom[0];
+ points2D[1].y = tgpi->bottom[1];
+}
+
+/* create a circle */
+static void gp_primitive_circle(tGPDprimitive *tgpi, tGPspoint *points2D)
+{
+ const int totpoints = tgpi->tot_edges;
+ const float step = (2.0f * M_PI) / (float)(totpoints);
+ float center[2];
+ float radius[2];
+ float a = 0.0f;
+
+ /* TODO: Use math-lib functions for these? */
+ center[0] = tgpi->top[0] + ((tgpi->bottom[0] - tgpi->top[0]) / 2.0f);
+ center[1] = tgpi->top[1] + ((tgpi->bottom[1] - tgpi->top[1]) / 2.0f);
+ radius[0] = fabsf(((tgpi->bottom[0] - tgpi->top[0]) / 2.0f));
+ radius[1] = fabsf(((tgpi->bottom[1] - tgpi->top[1]) / 2.0f));
+
+ for (int i = 0; i < totpoints; i++) {
+ tGPspoint *p2d = &points2D[i];
+
+ p2d->x = (int)(center[0] + cosf(a) * radius[0]);
+ p2d->y = (int)(center[1] + sinf(a) * radius[1]);
+ a += step;
+ }
+}
+
+/* Helper: Update shape of the stroke */
+static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
+{
+ ToolSettings *ts = tgpi->scene->toolsettings;
+ bGPdata *gpd = tgpi->gpd;
+ bGPDstroke *gps = tgpi->gpf->strokes.first;
+
+ /* realloc points to new size */
+ /* TODO: only do this if the size has changed? */
+ gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * tgpi->tot_edges);
+ gps->dvert = MEM_reallocN(gps->dvert, sizeof(MDeformVert) * tgpi->tot_edges);
+ gps->totpoints = tgpi->tot_edges;
+
+ /* compute screen-space coordinates for points */
+ tGPspoint *points2D = MEM_callocN(sizeof(tGPspoint) * tgpi->tot_edges, "gp primitive points2D");
+ switch (tgpi->type) {
+ case GP_STROKE_BOX:
+ gp_primitive_rectangle(tgpi, points2D);
+ break;
+ case GP_STROKE_LINE:
+ gp_primitive_line(tgpi, points2D);
+ break;
+ case GP_STROKE_CIRCLE:
+ gp_primitive_circle(tgpi, points2D);
+ break;
+ default:
+ break;
+ }
+
+ /* convert screen-coordinates to 3D coordinates */
+ for (int i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+ MDeformVert *dvert = &gps->dvert[i];
+ tGPspoint *p2d = &points2D[i];
+
+
+ /* convert screen-coordinates to 3D coordinates */
+ gp_stroke_convertcoords_tpoint(tgpi->scene, tgpi->ar, tgpi->v3d, tgpi->ob, tgpi->gpl, p2d, NULL, &pt->x);
+
+ pt->pressure = 1.0f;
+ pt->strength = tgpi->brush->gpencil_settings->draw_strength;
+ pt->time = 0.0f;
+
+ dvert->totweight = 0;
+ dvert->dw = NULL;
+ }
+
+ /* if axis locked, reproject to plane locked */
+ if (tgpi->lock_axis > GP_LOCKAXIS_NONE) {
+ bGPDspoint *tpt = gps->points;
+ float origin[3];
+ ED_gp_get_drawing_reference(tgpi->v3d, tgpi->scene, tgpi->ob, tgpi->gpl,
+ ts->gpencil_v3d_align, origin);
+
+ for (int i = 0; i < gps->totpoints; i++, tpt++) {
+ ED_gp_project_point_to_plane(tgpi->ob, tgpi->rv3d, origin,
+ ts->gp_sculpt.lock_axis - 1,
+ tpt);
+ }
+ }
+
+ /* 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->gpd, tgpi->gpl, pt);
+ }
+
+ /* force fill recalc */
+ gps->flag |= GP_STROKE_RECALC_CACHES;
+
+ /* free temp data */
+ MEM_SAFE_FREE(points2D);
+
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+}
+
+/* Update screen and stroke */
+static void gpencil_primitive_update(bContext *C, wmOperator *op, tGPDprimitive *tgpi)
+{
+ /* update indicator in header */
+ gpencil_primitive_status_indicators(C, tgpi);
+ /* apply... */
+ 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);
+}
+
+/* ----------------------- */
+
+/* Exit and free memory */
+static void gpencil_primitive_exit(bContext *C, wmOperator *op)
+{
+ tGPDprimitive *tgpi = op->customdata;
+ bGPdata *gpd = tgpi->gpd;
+
+ /* don't assume that operator data exists at all */
+ if (tgpi) {
+ /* remove drawing handler */
+ if (tgpi->draw_handle_3d) {
+ ED_region_draw_cb_exit(tgpi->ar->type, tgpi->draw_handle_3d);
+ }
+
+ /* clear status message area */
+ ED_workspace_status_text(C, NULL);
+
+ /* finally, free memory used by temp data */
+ BKE_gpencil_free_strokes(tgpi->gpf);
+ MEM_freeN(tgpi->gpf);
+ MEM_freeN(tgpi);
+ }
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+
+ /* clear pointer */
+ op->customdata = NULL;
+}
+
+/* Init new temporary primitive data */
+static void gpencil_primitive_init(bContext *C, wmOperator *op)
+{
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
+ /* create temporary operator data */
+ tGPDprimitive *tgpi = MEM_callocN(sizeof(tGPDprimitive), "GPencil Primitive Data");
+ op->customdata = tgpi;
+
+ /* set current scene and window info */
+ tgpi->scene = scene;
+ tgpi->ob = CTX_data_active_object(C);
+ tgpi->sa = CTX_wm_area(C);
+ tgpi->ar = CTX_wm_region(C);
+ tgpi->rv3d = tgpi->ar->regiondata;
+ tgpi->v3d = tgpi->sa->spacedata.first;
+ tgpi->depsgraph = CTX_data_depsgraph(C);
+ tgpi->win = CTX_wm_window(C);
+
+ /* set current frame number */
+ tgpi->cframe = cfra_eval;
+
+ /* set GP datablock */
+ tgpi->gpd = gpd;
+
+ /* getcolor info */
+ tgpi->mat = BKE_gpencil_material_ensure(bmain, tgpi->ob);
+
+ /* set parameters */
+ tgpi->type = RNA_enum_get(op->ptr, "type");
+
+ /* if circle set default to 32 */
+ if (tgpi->type == GP_STROKE_CIRCLE) {
+ RNA_int_set(op->ptr, "edges", 32);
+ }
+ else if (tgpi->type == GP_STROKE_BOX) {
+ RNA_int_set(op->ptr, "edges", 4);
+ }
+ else { /* LINE */
+ RNA_int_set(op->ptr, "edges", 2);
+ }
+
+ tgpi->tot_edges = RNA_int_get(op->ptr, "edges");
+ tgpi->flag = IDLE;
+
+ tgpi->lock_axis = ts->gp_sculpt.lock_axis;
+
+ /* set temp layer, frame and stroke */
+ gp_primitive_set_initdata(C, tgpi);
+}
+
+/* ----------------------- */
+
+/* Invoke handler: Initialize the operator */
+static int gpencil_primitive_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ wmWindow *win = CTX_wm_window(C);
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ tGPDprimitive *tgpi = NULL;
+
+ /* initialize operator runtime data */
+ gpencil_primitive_init(C, op);
+ tgpi = op->customdata;
+
+ /* if in tools region, wait till we get to the main (3d-space)
+ * region before allowing drawing to take place.
+ */
+ op->flag |= OP_IS_MODAL_CURSOR_REGION;
+
+ /* Enable custom drawing handlers */
+ tgpi->draw_handle_3d = ED_region_draw_cb_activate(tgpi->ar->type, gpencil_primitive_draw_3d, tgpi, REGION_DRAW_POST_VIEW);
+
+ /* set cursor to indicate modal */
+ WM_cursor_modal_set(win, BC_CROSSCURSOR);
+
+ /* update sindicator in header */
+ gpencil_primitive_status_indicators(C, tgpi);
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+
+ /* add a modal handler for this operator */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* Helper to complete a primitive */
+static void gpencil_primitive_done(bContext *C, wmOperator *op, wmWindow *win, tGPDprimitive *tgpi)
+{
+ bGPDframe *gpf;
+ bGPDstroke *gps;
+
+ /* return to normal cursor and header status */
+ ED_workspace_status_text(C, NULL);
+ WM_cursor_modal_restore(win);
+
+ /* insert keyframes as required... */
+ gpf = BKE_gpencil_layer_getframe(tgpi->gpl, tgpi->cframe, GP_GETFRAME_ADD_NEW);
+
+ /* prepare stroke to get transfered */
+ gps = tgpi->gpf->strokes.first;
+ if (gps) {
+ gps->thickness = tgpi->brush->size;
+ gps->flag |= GP_STROKE_RECALC_CACHES;
+ }
+
+ /* transfer stroke from temporary buffer to the actual frame */
+ BLI_movelisttolist(&gpf->strokes, &tgpi->gpf->strokes);
+ BLI_assert(BLI_listbase_is_empty(&tgpi->gpf->strokes));
+
+ /* clean up temp data */
+ gpencil_primitive_exit(C, op);
+}
+
+/* Modal handler: Events handling during interactive part */
+static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ tGPDprimitive *tgpi = op->customdata;
+ wmWindow *win = CTX_wm_window(C);
+ const bool has_numinput = hasNumInput(&tgpi->num);
+
+ switch (event->type) {
+ case LEFTMOUSE:
+ if ((event->val == KM_PRESS) && (tgpi->flag == IDLE)) {
+ /* start drawing primitive */
+ /* TODO: Ignore if not in main region yet */
+ tgpi->flag = IN_PROGRESS;
+
+ tgpi->top[0] = event->mval[0];
+ tgpi->top[1] = event->mval[1];
+
+ tgpi->bottom[0] = event->mval[0];
+ tgpi->bottom[1] = event->mval[1];
+ }
+ else if ((event->val == KM_RELEASE) && (tgpi->flag == IN_PROGRESS)) {
+ /* stop drawing primitive */
+ tgpi->flag = IDLE;
+ gpencil_primitive_done(C, op, win, tgpi);
+ /* done! */
+ return OPERATOR_FINISHED;
+ }
+ else {
+ if (G.debug & G_DEBUG) {
+ printf("GP Add Primitive Modal: LEFTMOUSE %d, Status = %d\n", event->val, tgpi->flag);
+ }
+ }
+ break;
+ case RETKEY: /* confirm */
+ {
+ tgpi->flag = IDLE;
+ gpencil_primitive_done(C, op, win, tgpi);
+ /* done! */
+ return OPERATOR_FINISHED;
+ }
+
+ case ESCKEY: /* cancel */
+ case RIGHTMOUSE:
+ {
+ /* return to normal cursor and header status */
+ ED_workspace_status_text(C, NULL);
+ WM_cursor_modal_restore(win);
+
+ /* clean up temp data */
+ gpencil_primitive_exit(C, op);
+
+ /* canceled! */
+ return OPERATOR_CANCELLED;
+ }
+
+ case WHEELUPMOUSE:
+ {
+ if (tgpi->type == GP_STROKE_CIRCLE) {
+ tgpi->tot_edges = tgpi->tot_edges + 1;
+ CLAMP(tgpi->tot_edges, MIN_EDGES, MAX_EDGES);
+ RNA_int_set(op->ptr, "edges", tgpi->tot_edges);
+
+ /* update screen */
+ gpencil_primitive_update(C, op, tgpi);
+ }
+ break;
+ }
+ case WHEELDOWNMOUSE:
+ {
+ if (tgpi->type == GP_STROKE_CIRCLE) {
+ tgpi->tot_edges = tgpi->tot_edges - 1;
+ CLAMP(tgpi->tot_edges, MIN_EDGES, MAX_EDGES);
+ RNA_int_set(op->ptr, "edges", tgpi->tot_edges);
+
+ /* update screen */
+ gpencil_primitive_update(C, op, tgpi);
+ }
+ break;
+ }
+ case MOUSEMOVE: /* calculate new position */
+ {
+ /* only handle mousemove if not doing numinput */
+ if (has_numinput == false) {
+ /* update position of mouse */
+ tgpi->bottom[0] = event->mval[0];
+ tgpi->bottom[1] = event->mval[1];
+ if (tgpi->flag == IDLE) {
+ tgpi->top[0] = event->mval[0];
+ tgpi->top[1] = event->mval[1];
+ }
+ /* Keep square if shift key */
+ if (event->shift) {
+ tgpi->bottom[1] = tgpi->top[1] - (tgpi->bottom[0] - tgpi->top[0]);
+ }
+ /* update screen */
+ gpencil_primitive_update(C, op, tgpi);
+ }
+ break;
+ }
+ default:
+ {
+ if ((event->val == KM_PRESS) && handleNumInput(C, &tgpi->num, event)) {
+ float value;
+
+ /* Grab data from numeric input, and store this new value (the user see an int) */
+ value = tgpi->tot_edges;
+ applyNumInput(&tgpi->num, &value);
+ tgpi->tot_edges = value;
+
+ CLAMP(tgpi->tot_edges, MIN_EDGES, MAX_EDGES);
+ RNA_int_set(op->ptr, "edges", tgpi->tot_edges);
+
+ /* update screen */
+ gpencil_primitive_update(C, op, tgpi);
+
+ break;
+ }
+ else {
+ /* unhandled event - allow to pass through */
+ return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
+ }
+ }
+ }
+
+ /* still running... */
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* Cancel handler */
+static void gpencil_primitive_cancel(bContext *C, wmOperator *op)
+{
+ /* this is just a wrapper around exit() */
+ gpencil_primitive_exit(C, op);
+}
+
+void GPENCIL_OT_primitive(wmOperatorType *ot)
+{
+ static EnumPropertyItem primitive_type[] = {
+ { GP_STROKE_BOX, "BOX", 0, "Box", "" },
+ { GP_STROKE_LINE, "LINE", 0, "Line", "" },
+ { GP_STROKE_CIRCLE, "CIRCLE", 0, "Circle", "" },
+ { 0, NULL, 0, NULL, NULL }
+ };
+
+ /* identifiers */
+ ot->name = "Grease Pencil Shapes";
+ ot->idname = "GPENCIL_OT_primitive";
+ ot->description = "Create predefined grease pencil stroke shapes";
+
+ /* callbacks */
+ ot->invoke = gpencil_primitive_invoke;
+ ot->modal = gpencil_primitive_modal;
+ ot->cancel = gpencil_primitive_cancel;
+ ot->poll = gpencil_primitive_add_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
+
+ /* properties */
+ RNA_def_int(ot->srna, "edges", 4, MIN_EDGES, MAX_EDGES, "Edges", "Number of polygon edges", MIN_EDGES, MAX_EDGES);
+ RNA_def_enum(ot->srna, "type", primitive_type, GP_STROKE_BOX, "Type", "Type of shape");
+}
+
+/* *************************************************************** */
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index dd556e99264..3e0caa8d5d8 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -43,6 +43,7 @@
#include "DNA_gpencil_types.h"
#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
#include "DNA_screen_types.h"
#include "DNA_object_types.h"
@@ -62,6 +63,9 @@
#include "ED_gpencil.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
#include "gpencil_intern.h"
/* ********************************************** */
@@ -71,8 +75,8 @@ static bool gpencil_select_poll(bContext *C)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
- /* we just need some visible strokes, and to be in editmode */
- if ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
+ /* we just need some visible strokes, and to be in editmode or other modes only to catch event */
+ if (GPENCIL_ANY_MODE(gpd)) {
/* TODO: include a check for visible strokes? */
if (gpd->layers.first)
return true;
@@ -94,6 +98,11 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ /* if not edit/sculpt mode, the event is catched but not processed */
+ if (GPENCIL_NONE_EDIT_MODE(gpd)) {
+ return OPERATOR_CANCELLED;
+ }
+
/* for "toggle", test for existing selected strokes */
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
@@ -180,6 +189,11 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op)
}
/* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
@@ -213,6 +227,11 @@ static int gpencil_select_linked_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ /* if not edit/sculpt mode, the event is catched but not processed */
+ if (GPENCIL_NONE_EDIT_MODE(gpd)) {
+ return OPERATOR_CANCELLED;
+ }
+
/* select all points in selected strokes */
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
@@ -228,6 +247,11 @@ static int gpencil_select_linked_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
@@ -248,6 +272,86 @@ void GPENCIL_OT_select_linked(wmOperatorType *ot)
}
/* ********************************************** */
+/* Select Alternate */
+
+static int gpencil_select_alternate_exec(bContext *C, wmOperator *op)
+{
+ const bool unselect_ends = RNA_boolean_get(op->ptr, "unselect_ends");
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+
+ if (gpd == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* if not edit/sculpt mode, the event is catched but not processed */
+ if (GPENCIL_NONE_EDIT_MODE(gpd)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* select all points in selected strokes */
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ if ((gps->flag & GP_STROKE_SELECT) && (gps->totpoints > 1)) {
+ bGPDspoint *pt;
+ int row = 0;
+ int start = 0;
+ if (unselect_ends) {
+ start = 1;
+ }
+
+ for (int i = start; i < gps->totpoints; i++) {
+ pt = &gps->points[i];
+ if ((row % 2) == 0) {
+ pt->flag |= GP_SPOINT_SELECT;
+ }
+ else {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+ row++;
+ }
+
+ /* unselect start and end points */
+ if (unselect_ends) {
+ pt = &gps->points[0];
+ pt->flag &= ~GP_SPOINT_SELECT;
+
+ pt = &gps->points[gps->totpoints - 1];
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ /* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
+ WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_select_alternate(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Alternated";
+ ot->idname = "GPENCIL_OT_select_alternate";
+ ot->description = "Select alternative points in same strokes as already selected points";
+
+ /* callbacks */
+ ot->exec = gpencil_select_alternate_exec;
+ ot->poll = gpencil_select_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "unselect_ends", true, "Unselect Ends", "Do not select the first and last point of the stroke");
+}
+
+/* ********************************************** */
/* Select Grouped */
typedef enum eGP_SelectGrouped {
@@ -266,11 +370,12 @@ 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)
{
- Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0);
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0);
bGPDstroke *gps;
bool found = false;
@@ -309,10 +414,7 @@ static void gp_select_same_layer(bContext *C)
/* Select all strokes with same colors as selected ones */
static void gp_select_same_color(bContext *C)
{
- /* First, build set containing all the colors of selected strokes
- * - We use the palette names, so that we can select all strokes with one
- * (potentially missing) color, and remap them to something else
- */
+ /* First, build set containing all the colors of selected strokes */
GSet *selected_colors = BLI_gset_str_new("GP Selected Colors");
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
@@ -321,7 +423,7 @@ static void gp_select_same_color(bContext *C)
/* add instead of insert here, otherwise the uniqueness check gets skipped,
* and we get many duplicate entries...
*/
- BLI_gset_add(selected_colors, gps->colorname);
+ BLI_gset_add(selected_colors, &gps->mat_nr);
}
}
CTX_DATA_END;
@@ -329,7 +431,7 @@ static void gp_select_same_color(bContext *C)
/* Second, select any visible stroke that uses these colors */
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
- if (BLI_gset_haskey(selected_colors, gps->colorname)) {
+ if (BLI_gset_haskey(selected_colors, &gps->mat_nr)) {
/* select this stroke */
bGPDspoint *pt;
int i;
@@ -342,6 +444,11 @@ static void gp_select_same_color(bContext *C)
}
}
CTX_DATA_END;
+
+ /* free memomy */
+ if (selected_colors != NULL) {
+ BLI_gset_free(selected_colors, NULL);
+ }
}
@@ -350,6 +457,11 @@ static void gp_select_same_color(bContext *C)
static int gpencil_select_grouped_exec(bContext *C, wmOperator *op)
{
eGP_SelectGrouped mode = RNA_enum_get(op->ptr, "type");
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ /* if not edit/sculpt mode, the event is catched but not processed */
+ if (GPENCIL_NONE_EDIT_MODE(gpd)) {
+ return OPERATOR_CANCELLED;
+ }
switch (mode) {
case GP_SEL_SAME_LAYER:
@@ -365,6 +477,11 @@ static int gpencil_select_grouped_exec(bContext *C, wmOperator *op)
}
/* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
@@ -399,6 +516,12 @@ void GPENCIL_OT_select_grouped(wmOperatorType *ot)
static int gpencil_select_first_exec(bContext *C, wmOperator *op)
{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ /* if not edit/sculpt mode, the event is catched but not processed */
+ if (GPENCIL_NONE_EDIT_MODE(gpd)) {
+ return OPERATOR_CANCELLED;
+ }
+
const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes");
const bool extend = RNA_boolean_get(op->ptr, "extend");
@@ -429,6 +552,11 @@ static int gpencil_select_first_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
@@ -459,6 +587,12 @@ void GPENCIL_OT_select_first(wmOperatorType *ot)
static int gpencil_select_last_exec(bContext *C, wmOperator *op)
{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ /* if not edit/sculpt mode, the event is catched but not processed */
+ if (GPENCIL_NONE_EDIT_MODE(gpd)) {
+ return OPERATOR_CANCELLED;
+ }
+
const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes");
const bool extend = RNA_boolean_get(op->ptr, "extend");
@@ -489,6 +623,11 @@ static int gpencil_select_last_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
@@ -519,6 +658,12 @@ void GPENCIL_OT_select_last(wmOperatorType *ot)
static int gpencil_select_more_exec(bContext *C, wmOperator *UNUSED(op))
{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ /* if not edit/sculpt mode, the event is catched but not processed */
+ if (GPENCIL_NONE_EDIT_MODE(gpd)) {
+ return OPERATOR_CANCELLED;
+ }
+
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
if (gps->flag & GP_STROKE_SELECT) {
@@ -565,6 +710,11 @@ static int gpencil_select_more_exec(bContext *C, wmOperator *UNUSED(op))
CTX_DATA_END;
/* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
@@ -589,6 +739,12 @@ void GPENCIL_OT_select_more(wmOperatorType *ot)
static int gpencil_select_less_exec(bContext *C, wmOperator *UNUSED(op))
{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ /* if not edit/sculpt mode, the event is catched but not processed */
+ if (GPENCIL_NONE_EDIT_MODE(gpd)) {
+ return OPERATOR_CANCELLED;
+ }
+
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
if (gps->flag & GP_STROKE_SELECT) {
@@ -636,6 +792,11 @@ static int gpencil_select_less_exec(bContext *C, wmOperator *UNUSED(op))
CTX_DATA_END;
/* updates */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
@@ -665,7 +826,7 @@ void GPENCIL_OT_select_less(wmOperatorType *ot)
static bool gp_stroke_do_circle_sel(
bGPDstroke *gps, GP_SpaceConversion *gsc,
const int mx, const int my, const int radius,
- const bool select, rcti *rect, const bool parented, float diff_mat[4][4])
+ const bool select, rcti *rect, float diff_mat[4][4])
{
bGPDspoint *pt1, *pt2;
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
@@ -673,14 +834,9 @@ static bool gp_stroke_do_circle_sel(
bool changed = false;
if (gps->totpoints == 1) {
- if (!parented) {
- gp_point_to_xy(gsc, gps, gps->points, &x0, &y0);
- }
- else {
- bGPDspoint pt_temp;
- gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
- gp_point_to_xy(gsc, gps, &pt_temp, &x0, &y0);
- }
+ bGPDspoint pt_temp;
+ gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
+ gp_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)) {
@@ -708,18 +864,12 @@ static bool gp_stroke_do_circle_sel(
/* get points to work with */
pt1 = gps->points + i;
pt2 = gps->points + i + 1;
- if (!parented) {
- gp_point_to_xy(gsc, gps, pt1, &x0, &y0);
- gp_point_to_xy(gsc, gps, pt2, &x1, &y1);
- }
- else {
- bGPDspoint npt;
- gp_point_to_parent_space(pt1, diff_mat, &npt);
- gp_point_to_xy(gsc, gps, &npt, &x0, &y0);
+ 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);
- }
+ 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)) ||
@@ -763,6 +913,12 @@ static bool gp_stroke_do_circle_sel(
static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ /* if not edit/sculpt mode, the event is catched but not processed */
+ if (GPENCIL_NONE_EDIT_MODE(gpd)) {
+ return OPERATOR_CANCELLED;
+ }
+
ScrArea *sa = CTX_wm_area(C);
const int mx = RNA_int_get(op->ptr, "x");
@@ -798,13 +954,17 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
{
changed |= gp_stroke_do_circle_sel(
- gps, &gsc, mx, my, radius, select, &rect,
- (gpl->parent != NULL), diff_mat);
+ gps, &gsc, mx, my, radius, select, &rect, diff_mat);
}
GP_EDITABLE_STROKES_END;
/* updates */
if (changed) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
}
@@ -826,7 +986,7 @@ void GPENCIL_OT_select_circle(wmOperatorType *ot)
ot->cancel = WM_gesture_circle_cancel;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
/* properties */
WM_operator_properties_gesture_circle_select(ot);
@@ -837,10 +997,11 @@ void GPENCIL_OT_select_circle(wmOperatorType *ot)
static int gpencil_border_select_exec(bContext *C, wmOperator *op)
{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
ScrArea *sa = CTX_wm_area(C);
const bool select = !RNA_boolean_get(op->ptr, "deselect");
- const bool extend = RNA_boolean_get(op->ptr, "extend");
+ const bool extend = RNA_boolean_get(op->ptr, "extend") && ((gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0);
GP_SpaceConversion gsc = {NULL};
rcti rect = {0};
@@ -888,14 +1049,9 @@ static int gpencil_border_select_exec(bContext *C, wmOperator *op)
int x0, y0;
/* convert point coords to screenspace */
- if (gpl->parent == NULL) {
- gp_point_to_xy(&gsc, gps, pt, &x0, &y0);
- }
- else {
- bGPDspoint pt2;
- gp_point_to_parent_space(pt, diff_mat, &pt2);
- gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0);
- }
+ bGPDspoint pt2;
+ gp_point_to_parent_space(pt, diff_mat, &pt2);
+ gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0);
/* test if in selection rect */
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0)) {
@@ -915,8 +1071,20 @@ static int gpencil_border_select_exec(bContext *C, wmOperator *op)
}
GP_EDITABLE_STROKES_END;
+ /* if paint mode,delete selected points */
+ if (gpd->flag & GP_DATA_STROKE_PAINTMODE) {
+ gp_delete_selected_point_wrap(C);
+ changed = true;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ }
+
/* updates */
if (changed) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
}
@@ -939,7 +1107,7 @@ void GPENCIL_OT_select_border(wmOperatorType *ot)
ot->poll = gpencil_select_poll;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
/* rna */
WM_operator_properties_gesture_border_select(ot);
@@ -950,10 +1118,11 @@ void GPENCIL_OT_select_border(wmOperatorType *ot)
static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
GP_SpaceConversion gsc = {NULL};
rcti rect = {0};
- const bool extend = RNA_boolean_get(op->ptr, "extend");
+ const bool extend = RNA_boolean_get(op->ptr, "extend") && ((gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0);
const bool select = !RNA_boolean_get(op->ptr, "deselect");
int mcords_tot;
@@ -997,14 +1166,9 @@ static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
int x0, y0;
/* convert point coords to screenspace */
- if (gpl->parent == NULL) {
- gp_point_to_xy(&gsc, gps, pt, &x0, &y0);
- }
- else {
- bGPDspoint pt2;
- gp_point_to_parent_space(pt, diff_mat, &pt2);
- gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0);
- }
+ bGPDspoint pt2;
+ gp_point_to_parent_space(pt, diff_mat, &pt2);
+ gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0);
/* test if in lasso boundbox + within the lasso noose */
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0) &&
BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX))
@@ -1028,8 +1192,20 @@ static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
/* cleanup */
MEM_freeN((void *)mcords);
+ /* if paint mode,delete selected points */
+ if (gpd->flag & GP_DATA_STROKE_PAINTMODE) {
+ gp_delete_selected_point_wrap(C);
+ changed = true;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ }
+
/* updates */
if (changed) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
}
@@ -1049,7 +1225,7 @@ void GPENCIL_OT_select_lasso(wmOperatorType *ot)
ot->cancel = WM_gesture_lasso_cancel;
/* flags */
- ot->flag = OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
/* properties */
WM_operator_properties_gesture_lasso_select(ot);
@@ -1061,6 +1237,7 @@ void GPENCIL_OT_select_lasso(wmOperatorType *ot)
static int gpencil_select_exec(bContext *C, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
/* "radius" is simply a threshold (screen space) to make it easier to test with a tolerance */
const float radius = 0.75f * U.widget_unit;
@@ -1102,14 +1279,9 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
int xy[2];
- if (gpl->parent == NULL) {
- gp_point_to_xy(&gsc, gps, pt, &xy[0], &xy[1]);
- }
- else {
- bGPDspoint pt2;
- gp_point_to_parent_space(pt, diff_mat, &pt2);
- gp_point_to_xy(&gsc, gps, &pt2, &xy[0], &xy[1]);
- }
+ bGPDspoint pt2;
+ gp_point_to_parent_space(pt, diff_mat, &pt2);
+ gp_point_to_xy(&gsc, gps, &pt2, &xy[0], &xy[1]);
/* do boundbox check first */
if (!ELEM(V2D_IS_CLIPPED, xy[0], xy[1])) {
@@ -1197,6 +1369,11 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
/* updates */
if (hit_point != NULL) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+
+ /* copy on write tag is needed, or else no refresh happens */
+ DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
}
@@ -1224,7 +1401,7 @@ void GPENCIL_OT_select(wmOperatorType *ot)
ot->poll = gpencil_select_poll;
/* flag */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
/* properties */
WM_operator_properties_mouse_select(ot);
diff --git a/source/blender/editors/gpencil/gpencil_undo.c b/source/blender/editors/gpencil/gpencil_undo.c
index d35df8bc380..708d8f37e58 100644
--- a/source/blender/editors/gpencil/gpencil_undo.c
+++ b/source/blender/editors/gpencil/gpencil_undo.c
@@ -36,6 +36,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_gpencil_types.h"
+#include "DNA_object_types.h"
#include "DNA_listBase.h"
#include "DNA_windowmanager_types.h"
@@ -51,6 +52,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "DEG_depsgraph.h"
+
#include "gpencil_intern.h"
typedef struct bGPundonode {
@@ -111,6 +114,9 @@ int ED_undo_gpencil_step(bContext *C, int step, const char *name)
}
}
}
+ /* drawing batch cache is dirty now */
+ DEG_id_tag_update(&new_gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ new_gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
}
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 8b65855f7c4..cd352579b4a 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -40,7 +40,9 @@
#include "BLT_translation.h"
#include "BLI_rand.h"
+#include "DNA_meshdata_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_brush_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -48,9 +50,13 @@
#include "DNA_view3d_types.h"
#include "BKE_action.h"
+#include "BKE_main.h"
+#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
-#include "BKE_main.h"
+#include "BKE_object.h"
+#include "BKE_paint.h"
+#include "BKE_material.h"
#include "BKE_tracking.h"
#include "WM_api.h"
@@ -65,8 +71,14 @@
#include "ED_gpencil.h"
#include "ED_clip.h"
#include "ED_view3d.h"
+#include "ED_object.h"
+#include "ED_screen.h"
+
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "gpencil_intern.h"
@@ -76,7 +88,7 @@
/* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it,
* when context info is not available.
*/
-bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrArea *sa, Object *ob, PointerRNA *ptr)
+bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, ScrArea *sa, Scene *scene, Object *ob, PointerRNA *r_ptr)
{
/* if there's an active area, check if the particular editor may
* have defined any special Grease Pencil context for editing...
@@ -85,26 +97,37 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
SpaceLink *sl = sa->spacedata.first;
switch (sa->spacetype) {
- case SPACE_VIEW3D: /* 3D-View */
+ /* XXX: Should we reduce reliance on context.gpencil_data for these cases? */
+ case SPACE_BUTS: /* properties */
+ case SPACE_INFO: /* header info (needed after workspaces merge) */
{
- BLI_assert(scene && ELEM(scene->toolsettings->gpencil_src,
- GP_TOOL_SOURCE_SCENE, GP_TOOL_SOURCE_OBJECT));
+ if (ob && (ob->type == OB_GPENCIL)) {
+ /* GP Object */
+ if (r_ptr) RNA_id_pointer_create(&ob->id, r_ptr);
+ return (bGPdata **)&ob->data;
+ }
+ else {
+ return NULL;
+ }
- if (scene->toolsettings->gpencil_src == GP_TOOL_SOURCE_OBJECT) {
- /* legacy behaviour for usage with old addons requiring object-linked to objects */
+ break;
+ }
- /* just in case no active/selected object... */
- if (ob && (ob->flag & SELECT)) {
- /* for now, as long as there's an object, default to using that in 3D-View */
- if (ptr) RNA_id_pointer_create(&ob->id, ptr);
- return &ob->gpd;
- }
- /* else: defaults to scene... */
+ case SPACE_TOPBAR: /* Topbar (needed after topbar merge) */
+ case SPACE_VIEW3D: /* 3D-View */
+ {
+ if (ob && (ob->type == OB_GPENCIL)) {
+ /* GP Object */
+ if (r_ptr) RNA_id_pointer_create(&ob->id, r_ptr);
+ return (bGPdata **)&ob->data;
}
else {
- if (ptr) RNA_id_pointer_create(&scene->id, ptr);
+ /* Annotations */
+ /* XXX: */
+ if (r_ptr) RNA_id_pointer_create(&scene->id, r_ptr);
return &scene->gpd;
}
+
break;
}
case SPACE_NODE: /* Nodes Editor */
@@ -114,7 +137,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
/* return the GP data for the active node block/node */
if (snode && snode->nodetree) {
/* for now, as long as there's an active node tree, default to using that in the Nodes Editor */
- if (ptr) RNA_id_pointer_create(&snode->nodetree->id, ptr);
+ if (r_ptr) RNA_id_pointer_create(&snode->nodetree->id, r_ptr);
return &snode->nodetree->gpd;
}
@@ -127,7 +150,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
/* for now, Grease Pencil data is associated with the space (actually preview region only) */
/* XXX our convention for everything else is to link to data though... */
- if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceSequenceEditor, sseq, ptr);
+ if (r_ptr) RNA_pointer_create(screen_id, &RNA_SpaceSequenceEditor, sseq, r_ptr);
return &sseq->gpd;
}
case SPACE_IMAGE: /* Image/UV Editor */
@@ -136,7 +159,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
/* for now, Grease Pencil data is associated with the space... */
/* XXX our convention for everything else is to link to data though... */
- if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, ptr);
+ if (r_ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, r_ptr);
return &sima->gpd;
}
case SPACE_CLIP: /* Nodes Editor */
@@ -151,15 +174,11 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
if (!track)
return NULL;
- if (ptr)
- RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr);
-
+ if (r_ptr) RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, r_ptr);
return &track->gpd;
}
else {
- if (ptr)
- RNA_id_pointer_create(&clip->id, ptr);
-
+ if (r_ptr) RNA_id_pointer_create(&clip->id, r_ptr);
return &clip->gpd;
}
}
@@ -170,79 +189,102 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
}
}
- /* just fall back on the scene's GP data */
- if (ptr) RNA_id_pointer_create((ID *)scene, ptr);
- return (scene) ? &scene->gpd : NULL;
+ return NULL;
}
/* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it */
-bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
+bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *r_ptr)
{
ID *screen_id = (ID *)CTX_wm_screen(C);
Scene *scene = CTX_data_scene(C);
ScrArea *sa = CTX_wm_area(C);
Object *ob = CTX_data_active_object(C);
- return ED_gpencil_data_get_pointers_direct(screen_id, scene, sa, ob, ptr);
+ return ED_gpencil_data_get_pointers_direct(screen_id, sa, scene, ob, r_ptr);
}
/* -------------------------------------------------------- */
/* Get the active Grease Pencil datablock, when context is not available */
-bGPdata *ED_gpencil_data_get_active_direct(ID *screen_id, Scene *scene, ScrArea *sa, Object *ob)
+bGPdata *ED_gpencil_data_get_active_direct(ID *screen_id, ScrArea *sa, Scene *scene, Object *ob)
{
- bGPdata **gpd_ptr = ED_gpencil_data_get_pointers_direct(screen_id, scene, sa, ob, NULL);
+ bGPdata **gpd_ptr = ED_gpencil_data_get_pointers_direct(screen_id, sa, scene, ob, NULL);
return (gpd_ptr) ? *(gpd_ptr) : NULL;
}
-/* Get the active Grease Pencil datablock */
+/**
+ * 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
+ */
bGPdata *ED_gpencil_data_get_active(const bContext *C)
{
bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
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
+ * 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
+ * like for ED_gpencil_data_get_active()
+ */
+bGPdata *ED_gpencil_data_get_active_evaluated(const bContext *C)
+{
+ ID *screen_id = (ID *)CTX_wm_screen(C);
+ ScrArea *sa = CTX_wm_area(C);
+
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+ Object *ob = CTX_data_active_object(C);
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+
+ /* if (ob && ob->type == OB_GPENCIL) BLI_assert(ob_eval->data == DEG_get_evaluated_id(ob->data)); */
+ return ED_gpencil_data_get_active_direct(screen_id, sa, scene_eval, ob_eval);
+}
+
+/* -------------------------------------------------------- */
+
+/**
+ * Utility to check whether the r_ptr output of ED_gpencil_data_get_pointers()
+ * is for annotation usage.
+ */
+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)
+ */
+ return ((owner_ptr) && (owner_ptr->type != &RNA_Object));
+}
+
/* -------------------------------------------------------- */
// XXX: this should be removed... We really shouldn't duplicate logic like this!
-bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, ViewLayer *view_layer)
+bGPdata *ED_gpencil_data_get_active_v3d(ViewLayer *view_layer)
{
Base *base = view_layer->basact;
bGPdata *gpd = NULL;
+
/* We have to make sure active object is actually visible and selected, else we must use default scene gpd,
* to be consistent with ED_gpencil_data_get_active's behavior.
*/
-
if (base && TESTBASE(base)) {
- gpd = base->object->gpd;
+ if (base->object->type == OB_GPENCIL)
+ gpd = base->object->data;
}
- return gpd ? gpd : scene->gpd;
+ return gpd ? gpd : NULL;
}
/* ******************************************************** */
/* Keyframe Indicator Checks */
/* Check whether there's an active GP keyframe on the current frame */
-bool ED_gpencil_has_keyframe_v3d(Scene *scene, Object *ob, int cfra)
+bool ED_gpencil_has_keyframe_v3d(Scene *UNUSED(scene), Object *ob, int cfra)
{
- /* just check both for now... */
- // XXX: this could get confusing (e.g. if only on the object, but other places don't show this)
- if (scene->gpd) {
- bGPDlayer *gpl = BKE_gpencil_layer_getactive(scene->gpd);
- if (gpl) {
- if (gpl->actframe) {
- // XXX: assumes that frame has been fetched already
- return (gpl->actframe->framenum == cfra);
- }
- else {
- /* XXX: disabled as could be too much of a penalty */
- /* return BKE_gpencil_layer_find_frame(gpl, cfra); */
- }
- }
- }
-
- if (ob && ob->gpd) {
- bGPDlayer *gpl = BKE_gpencil_layer_getactive(ob->gpd);
+ if (ob && ob->data && (ob->type == OB_GPENCIL)) {
+ bGPDlayer *gpl = BKE_gpencil_layer_getactive(ob->data);
if (gpl) {
if (gpl->actframe) {
// XXX: assumes that frame has been fetched already
@@ -281,28 +323,13 @@ bool gp_active_layer_poll(bContext *C)
bool gp_active_brush_poll(bContext *C)
{
ToolSettings *ts = CTX_data_tool_settings(C);
- bGPDbrush *brush = BKE_gpencil_brush_getactive(ts);
-
- return (brush != NULL);
-}
-
-/* poll callback for checking if there is an active palette */
-bool gp_active_palette_poll(bContext *C)
-{
- bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
-
- return (palette != NULL);
-}
-
-/* poll callback for checking if there is an active palette color */
-bool gp_active_palettecolor_poll(bContext *C)
-{
- bGPdata *gpd = ED_gpencil_data_get_active(C);
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
- bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette);
-
- return (palcolor != NULL);
+ Paint *paint = &ts->gp_paint->paint;
+ if (paint) {
+ return (paint->brush != NULL);
+ }
+ else {
+ return false;
+ }
}
/* ******************************************************** */
@@ -360,7 +387,7 @@ const EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(
/* Create new layer */
/* TODO: have some way of specifying that we don't want this? */
{
- /* active Keying Set */
+ /* "New Layer" entry */
item_tmp.identifier = "__CREATE__";
item_tmp.name = "New Layer";
item_tmp.value = -1;
@@ -392,7 +419,6 @@ const EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(
}
-
/* ******************************************************** */
/* Brush Tool Core */
@@ -426,7 +452,7 @@ bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]),
/* Stroke Validity Testing */
/* Check whether given stroke can be edited given the supplied context */
-// XXX: do we need additional flags for screenspace vs dataspace?
+/* TODO: do we need additional flags for screenspace vs dataspace? */
bool ED_gpencil_stroke_can_use_direct(const ScrArea *sa, const bGPDstroke *gps)
{
/* sanity check */
@@ -436,7 +462,7 @@ bool ED_gpencil_stroke_can_use_direct(const ScrArea *sa, const bGPDstroke *gps)
/* filter stroke types by flags + spacetype */
if (gps->flag & GP_STROKE_3DSPACE) {
/* 3D strokes - only in 3D view */
- return (sa->spacetype == SPACE_VIEW3D);
+ return ((sa->spacetype == SPACE_VIEW3D) || (sa->spacetype == SPACE_BUTS));
}
else if (gps->flag & GP_STROKE_2DIMAGE) {
/* Special "image" strokes - only in Image Editor */
@@ -460,59 +486,21 @@ bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps)
}
/* Check whether given stroke can be edited for the current color */
-bool ED_gpencil_stroke_color_use(const bGPDlayer *gpl, const bGPDstroke *gps)
+bool ED_gpencil_stroke_color_use(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps)
{
/* check if the color is editable */
- bGPDpalettecolor *palcolor = gps->palcolor;
- if (palcolor != NULL) {
- if (palcolor->flag & PC_COLOR_HIDE)
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
+
+ if (gp_style != NULL) {
+ if (gp_style->flag & GP_STYLE_COLOR_HIDE)
return false;
- if (((gpl->flag & GP_LAYER_UNLOCK_COLOR) == 0) && (palcolor->flag & PC_COLOR_LOCKED))
+ if (((gpl->flag & GP_LAYER_UNLOCK_COLOR) == 0) && (gp_style->flag & GP_STYLE_COLOR_LOCKED))
return false;
}
return true;
}
-/* Get palette color or create a new one */
-bGPDpalettecolor *ED_gpencil_stroke_getcolor(bGPdata *gpd, bGPDstroke *gps)
-{
- bGPDpalette *palette;
- bGPDpalettecolor *palcolor;
-
- if ((gps->palcolor != NULL) && ((gps->flag & GP_STROKE_RECALC_COLOR) == 0))
- return gps->palcolor;
-
- /* get palette */
- palette = BKE_gpencil_palette_getactive(gpd);
- if (palette == NULL) {
- palette = BKE_gpencil_palette_addnew(gpd, DATA_("GP_Palette"), true);
- }
- /* get color */
- palcolor = BKE_gpencil_palettecolor_getbyname(palette, gps->colorname);
- if (palcolor == NULL) {
- if (gps->palcolor == NULL) {
- palcolor = BKE_gpencil_palettecolor_addnew(palette, DATA_("Color"), true);
- /* set to a different color */
- ARRAY_SET_ITEMS(palcolor->color, 1.0f, 0.0f, 1.0f, 0.9f);
- }
- else {
- palcolor = BKE_gpencil_palettecolor_addnew(palette, gps->colorname, true);
- /* set old color and attributes */
- bGPDpalettecolor *gpscolor = gps->palcolor;
- copy_v4_v4(palcolor->color, gpscolor->color);
- copy_v4_v4(palcolor->fill, gpscolor->fill);
- palcolor->flag = gpscolor->flag;
- }
- }
-
- /* clear flag and set pointer */
- gps->flag &= ~GP_STROKE_RECALC_COLOR;
- gps->palcolor = palcolor;
-
- return palcolor;
-}
-
/* ******************************************************** */
/* Space Conversion */
@@ -573,9 +561,9 @@ void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *
}
/**
- * Change points position relative to parent object
+ * Change position relative to parent object
*/
-void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps)
+void gp_apply_parent(Depsgraph *depsgraph, Object *obact, bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps)
{
bGPDspoint *pt;
int i;
@@ -585,7 +573,7 @@ void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps)
float inverse_diff_mat[4][4];
float fpt[3];
- ED_gpencil_parent_location(gpl, diff_mat);
+ ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
for (i = 0; i < gps->totpoints; i++) {
@@ -598,14 +586,14 @@ void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps)
/**
* Change point position relative to parent object
*/
-void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt)
+void gp_apply_parent_point(Depsgraph *depsgraph, Object *obact, bGPdata *gpd, bGPDlayer *gpl, bGPDspoint *pt)
{
/* undo matrix */
float diff_mat[4][4];
float inverse_diff_mat[4][4];
float fpt[3];
- ED_gpencil_parent_location(gpl, diff_mat);
+ ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
mul_v3_m4v3(fpt, inverse_diff_mat, &pt->x);
@@ -770,194 +758,259 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene *scene, const float screen
}
/**
- * Apply smooth to stroke point
- * \param gps Stroke to smooth
- * \param i Point index
- * \param inf Amount of smoothing to apply
- * \param affect_pressure Apply smoothing to pressure values too?
+ * 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 depth: Depth array (via ED_view3d_autodist_depth())
+ * \param[out] r_out: The resulting 2D point data
*/
-bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure)
+void gp_stroke_convertcoords_tpoint(
+ Scene *scene, ARegion *ar, View3D *v3d,
+ Object *ob, bGPDlayer *gpl,
+ const tGPspoint *point2D, float *depth,
+ float r_out[3])
{
- bGPDspoint *pt = &gps->points[i];
- float pressure = 0.0f;
- float sco[3] = {0.0f};
+ ToolSettings *ts = scene->toolsettings;
+ const int mval[2] = {point2D->x, point2D->y};
- /* Do nothing if not enough points to smooth out */
- if (gps->totpoints <= 2) {
- return false;
+ if ((depth != NULL) && (ED_view3d_autodist_simple(ar, mval, r_out, 0, depth))) {
+ /* projecting onto 3D-Geometry
+ * - nothing more needs to be done here, since view_autodist_simple() has already done it
+ */
}
-
- /* Only affect endpoints by a fraction of the normal strength,
- * to prevent the stroke from shrinking too much
- */
- if ((i == 0) || (i == gps->totpoints - 1)) {
- inf *= 0.1f;
- }
-
- /* Compute smoothed coordinate by taking the ones nearby */
- /* XXX: This is potentially slow, and suffers from accumulation error as earlier points are handled before later ones */
- {
- // XXX: this is hardcoded to look at 2 points on either side of the current one (i.e. 5 items total)
- const int steps = 2;
- const float average_fac = 1.0f / (float)(steps * 2 + 1);
- int step;
-
- /* add the point itself */
- madd_v3_v3fl(sco, &pt->x, average_fac);
-
- if (affect_pressure) {
- pressure += pt->pressure * average_fac;
+ else {
+ float mval_f[2] = {(float)point2D->x, (float)point2D->y};
+ float mval_prj[2];
+ float rvec[3], dvec[3];
+ float zfac;
+
+ /* Current method just converts each point in screen-coordinates to
+ * 3D-coordinates using the 3D-cursor as reference.
+ */
+ ED_gp_get_drawing_reference(v3d, scene, ob, gpl, ts->gpencil_v3d_align, rvec);
+ zfac = ED_view3d_calc_zfac(ar->regiondata, rvec, NULL);
+
+ if (ED_view3d_project_float_global(ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ sub_v2_v2v2(mval_f, mval_prj, mval_f);
+ ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
+ sub_v3_v3v3(r_out, rvec, dvec);
+ }
+ else {
+ zero_v3(r_out);
}
+ }
+}
- /* n-steps before/after current point */
- // XXX: review how the endpoints are treated by this algorithm
- // XXX: falloff measures should also introduce some weighting variations, so that further-out points get less weight
- for (step = 1; step <= steps; step++) {
- bGPDspoint *pt1, *pt2;
- int before = i - step;
- int after = i + step;
-
- CLAMP_MIN(before, 0);
- CLAMP_MAX(after, gps->totpoints - 1);
-
- pt1 = &gps->points[before];
- pt2 = &gps->points[after];
-
- /* add both these points to the average-sum (s += p[i]/n) */
- madd_v3_v3fl(sco, &pt1->x, average_fac);
- madd_v3_v3fl(sco, &pt2->x, average_fac);
-
-#if 0
- /* XXX: Disabled because get weird result */
- /* do pressure too? */
- if (affect_pressure) {
- pressure += pt1->pressure * average_fac;
- pressure += pt2->pressure * average_fac;
+/**
+ * Get drawing reference point for conversion or projection of the stroke
+ * \param[out] r_vec : Reference point found
+ */
+void ED_gp_get_drawing_reference(
+ View3D *v3d, Scene *scene, Object *ob, bGPDlayer *UNUSED(gpl),
+ char align_flag, float r_vec[3])
+{
+ const float *fp = ED_view3d_cursor3d_get(scene, v3d)->location;
+
+ /* if using a gpencil object at cursor mode, can use the location of the object */
+ if (align_flag & GP_PROJECT_VIEWSPACE) {
+ if (ob && (ob->type == OB_GPENCIL)) {
+ /* fallback (no strokes) - use cursor or object location */
+ if (align_flag & GP_PROJECT_CURSOR) {
+ /* use 3D-cursor */
+ copy_v3_v3(r_vec, fp);
+ }
+ else {
+ /* use object location */
+ copy_v3_v3(r_vec, ob->obmat[3]);
}
-#endif
}
}
-
- /* Based on influence factor, blend between original and optimal smoothed coordinate */
- interp_v3_v3v3(&pt->x, &pt->x, sco, inf);
-
-#if 0
- /* XXX: Disabled because get weird result */
- if (affect_pressure) {
- pt->pressure = pressure;
+ else {
+ /* use 3D-cursor */
+ copy_v3_v3(r_vec, fp);
}
-#endif
-
- return true;
}
+
/**
-* Apply smooth for strength to stroke point
-* \param gps Stroke to smooth
-* \param i Point index
-* \param inf Amount of smoothing to apply
-*/
-bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf)
+ * Reproject all points of the stroke to a plane locked to axis to avoid stroke offset
+ */
+void ED_gp_project_stroke_to_plane(Object *ob, RegionView3D *rv3d, bGPDstroke *gps, const float origin[3], const int axis)
{
- bGPDspoint *ptb = &gps->points[i];
-
- /* Do nothing if not enough points */
- if (gps->totpoints <= 2) {
- return false;
+ float plane_normal[3];
+ float vn[3];
+
+ float ray[3];
+ float rpoint[3];
+
+ /* normal vector for a plane locked to axis */
+ zero_v3(plane_normal);
+ if (axis < 0) {
+ /* if the axis is not locked, need a vector to the view direction
+ * in order to get the right size of the stroke.
+ */
+ ED_view3d_global_to_vector(rv3d, origin, plane_normal);
+ }
+ else {
+ plane_normal[axis] = 1.0f;
+ /* if object, apply object rotation */
+ if (ob && (ob->type == OB_GPENCIL)) {
+ mul_mat3_m4_v3(ob->obmat, plane_normal);
+ }
}
- /* Compute theoretical optimal value using distances */
- bGPDspoint *pta, *ptc;
- int before = i - 1;
- int after = i + 1;
-
- CLAMP_MIN(before, 0);
- CLAMP_MAX(after, gps->totpoints - 1);
-
- pta = &gps->points[before];
- ptc = &gps->points[after];
+ /* Reproject the points in the plane */
+ for (int i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
- /* the optimal value is the corresponding to the interpolation of the strength
- * at the distance of point b
- */
- const float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
- const float optimal = (1.0f - fac) * pta->strength + fac * ptc->strength;
+ /* get a vector from the point with the current view direction of the viewport */
+ ED_view3d_global_to_vector(rv3d, &pt->x, vn);
- /* Based on influence factor, blend between original and optimal */
- ptb->strength = (1.0f - inf) * ptb->strength + inf * optimal;
+ /* calculate line extreme point to create a ray that cross the plane */
+ mul_v3_fl(vn, -50.0f);
+ add_v3_v3v3(ray, &pt->x, vn);
- return true;
+ /* if the line never intersect, the point is not changed */
+ if (isect_line_plane_v3(rpoint, &pt->x, ray, origin, plane_normal)) {
+ copy_v3_v3(&pt->x, rpoint);
+ }
+ }
}
/**
-* Apply smooth for thickness to stroke point (use pressure)
-* \param gps Stroke to smooth
-* \param i Point index
-* \param inf Amount of smoothing to apply
-*/
-bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf)
+ * Reproject given point to a plane locked to axis to avoid stroke offset
+ * \param[in, out] pt : Point to affect
+ */
+void ED_gp_project_point_to_plane(Object *ob, RegionView3D *rv3d, const float origin[3], const int axis, bGPDspoint *pt)
{
- bGPDspoint *ptb = &gps->points[i];
-
- /* Do nothing if not enough points */
- if (gps->totpoints <= 2) {
- return false;
+ float plane_normal[3];
+ float vn[3];
+
+ float ray[3];
+ float rpoint[3];
+
+ /* normal vector for a plane locked to axis */
+ zero_v3(plane_normal);
+ if (axis < 0) {
+ /* if the axis is not locked, need a vector to the view direction
+ * in order to get the right size of the stroke.
+ */
+ ED_view3d_global_to_vector(rv3d, origin, plane_normal);
+ }
+ else {
+ plane_normal[axis] = 1.0f;
+ /* if object, apply object rotation */
+ if (ob && (ob->type == OB_GPENCIL)) {
+ mul_mat3_m4_v3(ob->obmat, plane_normal);
+ }
}
- /* Compute theoretical optimal value using distances */
- bGPDspoint *pta, *ptc;
- int before = i - 1;
- int after = i + 1;
-
- CLAMP_MIN(before, 0);
- CLAMP_MAX(after, gps->totpoints - 1);
-
- pta = &gps->points[before];
- ptc = &gps->points[after];
- /* the optimal value is the corresponding to the interpolation of the pressure
- * at the distance of point b
- */
- float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
- float optimal = (1.0f - fac) * pta->pressure + fac * ptc->pressure;
+ /* Reproject the points in the plane */
+ /* get a vector from the point with the current view direction of the viewport */
+ ED_view3d_global_to_vector(rv3d, &pt->x, vn);
- /* Based on influence factor, blend between original and optimal */
- ptb->pressure = (1.0f - inf) * ptb->pressure + inf * optimal;
+ /* calculate line extrem point to create a ray that cross the plane */
+ mul_v3_fl(vn, -50.0f);
+ add_v3_v3v3(ray, &pt->x, vn);
- return true;
+ /* if the line never intersect, the point is not changed */
+ if (isect_line_plane_v3(rpoint, &pt->x, ray, origin, plane_normal)) {
+ copy_v3_v3(&pt->x, rpoint);
+ }
}
+/* ******************************************************** */
+/* Stroke Operations */
+// XXX: Check if these functions duplicate stuff in blenkernel, and/or whether we should just deduplicate
+
/**
* Subdivide a stroke once, by adding a point half way between each pair of existing points
* \param gps Stroke data
- * \param new_totpoints Total number of points (after subdividing)
+ * \param subdivide Number of times to subdivide
*/
-void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints)
+void gp_subdivide_stroke(bGPDstroke *gps, const int subdivide)
{
- /* Move points towards end of enlarged points array to leave space for new points */
- int y = 1;
- for (int i = gps->totpoints - 1; i > 0; i--) {
- gps->points[new_totpoints - y] = gps->points[i];
- y += 2;
- }
+ bGPDspoint *temp_points;
+ int totnewpoints, oldtotpoints;
+ int i2;
+
+ /* loop as many times as levels */
+ for (int s = 0; s < subdivide; s++) {
+ totnewpoints = gps->totpoints - 1;
+ /* duplicate points in a temp area */
+ temp_points = MEM_dupallocN(gps->points);
+ oldtotpoints = gps->totpoints;
+
+ /* resize the points arrys */
+ gps->totpoints += totnewpoints;
+ gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints);
+ gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints);
+ gps->flag |= GP_STROKE_RECALC_CACHES;
+
+ /* move points from last to first to new place */
+ i2 = gps->totpoints - 1;
+ for (int i = oldtotpoints - 1; i > 0; i--) {
+ bGPDspoint *pt = &temp_points[i];
+ bGPDspoint *pt_final = &gps->points[i2];
+ MDeformVert *dvert = &gps->dvert[i];
+ MDeformVert *dvert_final = &gps->dvert[i2];
+
+ copy_v3_v3(&pt_final->x, &pt->x);
+ pt_final->pressure = pt->pressure;
+ pt_final->strength = pt->strength;
+ pt_final->time = pt->time;
+ pt_final->flag = pt->flag;
+ pt_final->uv_fac = pt->uv_fac;
+ pt_final->uv_rot = pt->uv_rot;
+
+ dvert_final->totweight = dvert->totweight;
+ dvert_final->dw = dvert->dw;
+
+ i2 -= 2;
+ }
+ /* interpolate mid points */
+ i2 = 1;
+ for (int i = 0; i < oldtotpoints - 1; i++) {
+ bGPDspoint *pt = &temp_points[i];
+ bGPDspoint *next = &temp_points[i + 1];
+ bGPDspoint *pt_final = &gps->points[i2];
+ MDeformVert *dvert_final = &gps->dvert[i2];
+
+ /* add a half way point */
+ interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f);
+ pt_final->pressure = interpf(pt->pressure, next->pressure, 0.5f);
+ pt_final->strength = interpf(pt->strength, next->strength, 0.5f);
+ CLAMP(pt_final->strength, GPENCIL_STRENGTH_MIN, 1.0f);
+ pt_final->time = interpf(pt->time, next->time, 0.5f);
+ pt_final->uv_fac = interpf(pt->uv_fac, next->uv_fac, 0.5f);
+ pt_final->uv_rot = interpf(pt->uv_rot, next->uv_rot, 0.5f);
+
+ dvert_final->totweight = 0;
+ dvert_final->dw = NULL;
+
+ i2 += 2;
+ }
- /* Create interpolated points */
- for (int i = 0; i < new_totpoints - 1; i += 2) {
- bGPDspoint *prev = &gps->points[i];
- bGPDspoint *pt = &gps->points[i + 1];
- bGPDspoint *next = &gps->points[i + 2];
+ MEM_SAFE_FREE(temp_points);
- /* Interpolate all values */
- interp_v3_v3v3(&pt->x, &prev->x, &next->x, 0.5f);
+ /* move points to smooth stroke */
+ /* duplicate points in a temp area with the new subdivide data */
+ temp_points = MEM_dupallocN(gps->points);
- pt->pressure = interpf(prev->pressure, next->pressure, 0.5f);
- pt->strength = interpf(prev->strength, next->strength, 0.5f);
- CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
- pt->time = interpf(prev->time, next->time, 0.5f);
- }
+ /* extreme points are not changed */
+ for (int i = 0; i < gps->totpoints - 2; i++) {
+ bGPDspoint *pt = &temp_points[i];
+ bGPDspoint *next = &temp_points[i + 1];
+ bGPDspoint *pt_final = &gps->points[i + 1];
- /* Update to new total number of points */
- gps->totpoints = new_totpoints;
+ /* move point */
+ interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f);
+ }
+ /* free temp memory */
+ MEM_SAFE_FREE(temp_points);
+ }
}
/**
@@ -965,7 +1018,7 @@ void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints)
* \param gps Stroke data
* \param brush Brush data
*/
-void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush, RNG *rng)
+void gp_randomize_stroke(bGPDstroke *gps, Brush *brush, RNG *rng)
{
bGPDspoint *pt1, *pt2, *pt3;
float v1[3];
@@ -995,10 +1048,10 @@ void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush, RNG *rng)
normalize_v3(ortho);
/* Read all points and apply shift vector (first and last point not modified) */
- for (int i = 1; i < gps->totpoints - 1; ++i) {
+ for (int i = 1; i < gps->totpoints - 1; i++) {
bGPDspoint *pt = &gps->points[i];
/* get vector with shift (apply a division because random is too sensitive */
- const float fac = BLI_rng_get_float(rng) * (brush->draw_random_sub / 10.0f);
+ const float fac = BLI_rng_get_float(rng) * (brush->gpencil_settings->draw_random_sub / 10.0f);
float svec[3];
copy_v3_v3(svec, ortho);
if (BLI_rng_get_float(rng) > 0.5f) {
@@ -1011,31 +1064,46 @@ void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush, RNG *rng)
/* apply shift */
add_v3_v3(&pt->x, svec);
}
-
}
+
+/* ******************************************************** */
+/* Layer Parenting - Compute Parent Transforms */
+
/* calculate difference matrix */
-void ED_gpencil_parent_location(bGPDlayer *gpl, float diff_mat[4][4])
+void ED_gpencil_parent_location(
+ const Depsgraph *depsgraph, Object *obact, bGPdata *UNUSED(gpd),
+ bGPDlayer *gpl, float diff_mat[4][4])
{
- Object *ob = gpl->parent;
-
- if (ob == NULL) {
+ Object *ob_eval = depsgraph != NULL ? DEG_get_evaluated_object(depsgraph, obact) : obact;
+ Object *obparent = gpl->parent;
+ Object *obparent_eval = depsgraph != NULL ? DEG_get_evaluated_object(depsgraph, obparent) : obparent;
+
+ /* if not layer parented, try with object parented */
+ if (obparent_eval == NULL) {
+ if (ob_eval != NULL) {
+ if (ob_eval->type == OB_GPENCIL) {
+ copy_m4_m4(diff_mat, ob_eval->obmat);
+ return;
+ }
+ }
+ /* not gpencil object */
unit_m4(diff_mat);
return;
}
else {
if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) {
- mul_m4_m4m4(diff_mat, ob->obmat, gpl->inverse);
+ mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
return;
}
else if (gpl->partype == PARBONE) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, gpl->parsubstr);
+ bPoseChannel *pchan = BKE_pose_channel_find_name(obparent_eval->pose, gpl->parsubstr);
if (pchan) {
float tmp_mat[4][4];
- mul_m4_m4m4(tmp_mat, ob->obmat, pchan->pose_mat);
+ mul_m4_m4m4(tmp_mat, obparent_eval->obmat, pchan->pose_mat);
mul_m4_m4m4(diff_mat, tmp_mat, gpl->inverse);
}
else {
- mul_m4_m4m4(diff_mat, ob->obmat, gpl->inverse); /* if bone not found use object (armature) */
+ mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse); /* if bone not found use object (armature) */
}
return;
}
@@ -1046,7 +1114,7 @@ void ED_gpencil_parent_location(bGPDlayer *gpl, float diff_mat[4][4])
}
/* reset parent matrix for all layers */
-void ED_gpencil_reset_layers_parent(bGPdata *gpd)
+void ED_gpencil_reset_layers_parent(Depsgraph *depsgraph, Object *obact, bGPdata *gpd)
{
bGPDspoint *pt;
int i;
@@ -1071,7 +1139,7 @@ void ED_gpencil_reset_layers_parent(bGPdata *gpd)
/* only redo if any change */
if (!equals_m4m4(gpl->inverse, cur_mat)) {
/* first apply current transformation to all strokes */
- ED_gpencil_parent_location(gpl, diff_mat);
+ ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat);
for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
@@ -1086,90 +1154,582 @@ void ED_gpencil_reset_layers_parent(bGPdata *gpd)
}
}
/* ******************************************************** */
-bool ED_gpencil_stroke_minmax(
- const bGPDstroke *gps, const bool use_select,
- float r_min[3], float r_max[3])
+/* GP Object Stuff */
+
+/* Helper function to create new OB_GPENCIL Object */
+Object *ED_add_gpencil_object(bContext *C, Scene *scene, const float loc[3])
{
- const bGPDspoint *pt;
- int i;
- bool changed = false;
+ float rot[3] = {0.0f};
+
+ Object *ob = ED_object_add_type(C, OB_GPENCIL, NULL, loc, rot, false, scene->lay);
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if ((use_select == false) || (pt->flag & GP_SPOINT_SELECT)) {;
- minmax_v3v3_v3(r_min, r_max, &pt->x);
- changed = true;
+ /* define size */
+ BKE_object_obdata_size_init(ob, GP_OBGPENCIL_DEFAULT_SIZE);
+ /* create default brushes and colors */
+ ED_gpencil_add_defaults(C);
+
+ return ob;
+}
+
+/* Helper function to create default colors and drawing brushes */
+void ED_gpencil_add_defaults(bContext *C)
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob = CTX_data_active_object(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+
+ /* first try to reuse default material */
+ if (ob->actcol > 0) {
+ Material *ma = give_current_material(ob, ob->actcol);
+ if ((ma) && (ma->gp_style == NULL)) {
+ BKE_material_init_gpencil_settings(ma);
}
}
- return changed;
+
+ /* ensure color exist */
+ BKE_gpencil_material_ensure(bmain, ob);
+
+ Paint *paint = BKE_brush_get_gpencil_paint(ts);
+ /* if not exist, create a new one */
+ if (paint->brush == NULL) {
+ /* create new brushes */
+ BKE_brush_gpencil_presets(C);
+ }
+
}
-/* Dynamic Enums of GP Brushes */
-const EnumPropertyItem *ED_gpencil_brushes_enum_itemf(
- bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
- bool *r_free)
+/* ******************************************************** */
+/* Vertex Groups */
+
+/* assign points to vertex group */
+void ED_gpencil_vgroup_assign(bContext *C, Object *ob, float weight)
{
- ToolSettings *ts = CTX_data_tool_settings(C);
- bGPDbrush *brush;
- EnumPropertyItem *item = NULL, item_tmp = { 0 };
- int totitem = 0;
- int i = 0;
+ const int def_nr = ob->actdef - 1;
+ if (!BLI_findlink(&ob->defbase, def_nr))
+ return;
- if (ELEM(NULL, C, ts)) {
- return DummyRNA_DEFAULT_items;
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ if (gps->flag & GP_STROKE_SELECT) {
+ for (int i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+ MDeformVert *dvert = &gps->dvert[i];
+ if (pt->flag & GP_SPOINT_SELECT) {
+ BKE_gpencil_vgroup_add_point_weight(dvert, def_nr, weight);
+ }
+ }
+ }
}
+ CTX_DATA_END;
+}
- /* Existing brushes */
- for (brush = ts->gp_brushes.first; brush; brush = brush->next, i++) {
- item_tmp.identifier = brush->info;
- item_tmp.name = brush->info;
- item_tmp.value = i;
+/* remove points from vertex group */
+void ED_gpencil_vgroup_remove(bContext *C, Object *ob)
+{
+ const int def_nr = ob->actdef - 1;
+ if (!BLI_findlink(&ob->defbase, def_nr))
+ return;
- if (brush->flag & GP_BRUSH_ACTIVE)
- item_tmp.icon = ICON_BRUSH_DATA;
- else
- item_tmp.icon = ICON_NONE;
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ for (int i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+ MDeformVert *dvert = &gps->dvert[i];
- RNA_enum_item_add(&item, &totitem, &item_tmp);
+ if ((pt->flag & GP_SPOINT_SELECT) && (dvert->totweight > 0)) {
+ BKE_gpencil_vgroup_remove_point_weight(dvert, def_nr);
+ }
+ }
}
+ CTX_DATA_END;
+}
- RNA_enum_item_end(&item, &totitem);
- *r_free = true;
+/* select points of vertex group */
+void ED_gpencil_vgroup_select(bContext *C, Object *ob)
+{
+ const int def_nr = ob->actdef - 1;
+ if (!BLI_findlink(&ob->defbase, def_nr))
+ return;
- return item;
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ for (int i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+ MDeformVert *dvert = &gps->dvert[i];
+
+ if (BKE_gpencil_vgroup_use_index(dvert, def_nr) > -1.0f) {
+ pt->flag |= GP_SPOINT_SELECT;
+ gps->flag |= GP_STROKE_SELECT;
+ }
+ }
+ }
+ CTX_DATA_END;
}
-/* Dynamic Enums of GP Palettes */
-const EnumPropertyItem *ED_gpencil_palettes_enum_itemf(
- bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
- bool *r_free)
+/* unselect points of vertex group */
+void ED_gpencil_vgroup_deselect(bContext *C, Object *ob)
{
- bGPdata *gpd = CTX_data_gpencil_data(C);
- bGPDpalette *palette;
- EnumPropertyItem *item = NULL, item_tmp = { 0 };
- int totitem = 0;
- int i = 0;
+ const int def_nr = ob->actdef - 1;
+ if (!BLI_findlink(&ob->defbase, def_nr))
+ return;
- if (ELEM(NULL, C, gpd)) {
- return DummyRNA_DEFAULT_items;
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ for (int i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+ MDeformVert *dvert = &gps->dvert[i];
+
+ if (BKE_gpencil_vgroup_use_index(dvert, def_nr) > -1.0f) {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ gps->flag |= GP_STROKE_SELECT;
+ }
+ }
}
+ CTX_DATA_END;
+}
- /* Existing palettes */
- for (palette = gpd->palettes.first; palette; palette = palette->next, i++) {
- item_tmp.identifier = palette->info;
- item_tmp.name = palette->info;
- item_tmp.value = i;
+/* ******************************************************** */
+/* Cursor drawing */
- if (palette->flag & PL_PALETTE_ACTIVE)
- item_tmp.icon = ICON_COLOR;
- else
- item_tmp.icon = ICON_NONE;
+/* check if cursor is in drawing region */
+static bool gp_check_cursor_region(bContext *C, int mval[2])
+{
+ ARegion *ar = CTX_wm_region(C);
+ ScrArea *sa = CTX_wm_area(C);
+ /* TODO: add more spacetypes */
+ if (!ELEM(sa->spacetype, SPACE_VIEW3D)) {
+ return false;
+ }
+ if ((ar) && (ar->regiontype != RGN_TYPE_WINDOW)) {
+ return false;
+ }
+ else if (ar) {
+ rcti region_rect;
- RNA_enum_item_add(&item, &totitem, &item_tmp);
+ /* Perform bounds check using */
+ ED_region_visible_rect(ar, &region_rect);
+ return BLI_rcti_isect_pt_v(&region_rect, mval);
+ }
+ else {
+ return false;
}
+}
- RNA_enum_item_end(&item, &totitem);
- *r_free = true;
+/* draw eraser cursor */
+void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y)
+{
+ short radius = (short)brush->size;
- return item;
+ GPUVertFormat *format = immVertexFormat();
+ const uint shdr_pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ immUniformColor4ub(255, 100, 100, 20);
+ imm_draw_circle_fill_2d(shdr_pos, x, y, radius, 40);
+
+ immUnbindProgram();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+
+ immUniformColor4f(1.0f, 0.39f, 0.39f, 0.78f);
+ immUniform1i("colors_len", 0); /* "simple" mode */
+ immUniform1f("dash_width", 12.0f);
+ immUniform1f("dash_factor", 0.5f);
+
+ imm_draw_circle_wire_2d(shdr_pos, x, y, radius,
+ /* XXX Dashed shader gives bad results with sets of small segments currently,
+ * temp hack around the issue. :( */
+ max_ii(8, radius / 2)); /* was fixed 40 */
+
+ immUnbindProgram();
+
+ glDisable(GL_BLEND);
+ glDisable(GL_LINE_SMOOTH);
+}
+
+/* Helper callback for drawing the cursor itself */
+static void gp_brush_drawcursor(bContext *C, int x, int y, void *customdata)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ ARegion *ar = CTX_wm_region(C);
+
+ GP_BrushEdit_Settings *gset = &scene->toolsettings->gp_sculpt;
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ GP_EditBrush_Data *brush = NULL;
+ Brush *paintbrush = NULL;
+ Material *ma = NULL;
+ MaterialGPencilStyle *gp_style = NULL;
+ int *last_mouse_position = customdata;
+
+ if ((gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE)) {
+ brush = &gset->brush[gset->weighttype];
+ }
+ else {
+ brush = &gset->brush[gset->brushtype];
+ }
+
+ /* default radius and color */
+ float color[3] = {1.0f, 1.0f, 1.0f};
+ float darkcolor[3];
+ float radius = 3.0f;
+
+ int mval[2] = {x, y};
+ /* check if cursor is in drawing region and has valid datablock */
+ if ((!gp_check_cursor_region(C, mval)) || (gpd == NULL)) {
+ return;
+ }
+
+ /* for paint use paint brush size and color */
+ if (gpd->flag & GP_DATA_STROKE_PAINTMODE) {
+ paintbrush = BKE_brush_getactive_gpencil(scene->toolsettings);
+ /* while drawing hide */
+ if ((gpd->runtime.sbuffer_size > 0) &&
+ (paintbrush) && ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) &&
+ ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0))
+ {
+ return;
+ }
+
+ if (paintbrush) {
+ if ((paintbrush->gpencil_settings->flag & GP_BRUSH_ENABLE_CURSOR) == 0) {
+ return;
+ }
+
+ /* eraser has special shape and use a different shader program */
+ if (paintbrush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE) {
+ ED_gpencil_brush_draw_eraser(paintbrush, x, y);
+ return;
+ }
+
+ /* get current drawing color */
+ ma = BKE_gpencil_get_material_from_brush(paintbrush);
+ if (ma == NULL) {
+ BKE_gpencil_material_ensure(bmain, ob);
+ /* assign the first material to the brush */
+ ma = give_current_material(ob, 1);
+ paintbrush->gpencil_settings->material = ma;
+ }
+ gp_style = ma->gp_style;
+
+ /* after some testing, display the size of the brush is not practical because
+ * is too disruptive and the size of cursor does not change with zoom factor.
+ * The decision was to use a fix size, instead of paintbrush->thickness value.
+ */
+ if ((gp_style) && (GPENCIL_PAINT_MODE(gpd)) &&
+ ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) &&
+ ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) &&
+ (paintbrush->gpencil_settings->brush_type == GP_BRUSH_TYPE_DRAW))
+ {
+ radius = 2.0f;
+ copy_v3_v3(color, gp_style->stroke_rgba);
+ }
+ else {
+ radius = 5.0f;
+ copy_v3_v3(color, paintbrush->add_col);
+ }
+ }
+ else {
+ return;
+ }
+ }
+
+ /* for sculpt use sculpt brush size */
+ if (GPENCIL_SCULPT_OR_WEIGHT_MODE(gpd)) {
+ if (brush) {
+ if ((brush->flag & GP_EDITBRUSH_FLAG_ENABLE_CURSOR) == 0) {
+ return;
+ }
+
+ radius = brush->size;
+ if (brush->flag & (GP_EDITBRUSH_FLAG_INVERT | GP_EDITBRUSH_FLAG_TMP_INVERT)) {
+ copy_v3_v3(color, brush->curcolor_sub);
+ }
+ else {
+ copy_v3_v3(color, brush->curcolor_add);
+ }
+ }
+ }
+
+ /* draw icon */
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+
+ /* Inner Ring: Color from UI panel */
+ immUniformColor4f(color[0], color[1], color[2], 0.8f);
+ if ((gp_style) && (GPENCIL_PAINT_MODE(gpd)) &&
+ ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) &&
+ ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) &&
+ (paintbrush->gpencil_settings->brush_type == GP_BRUSH_TYPE_DRAW))
+ {
+ imm_draw_circle_fill_2d(pos, x, y, radius, 40);
+ }
+ else {
+ imm_draw_circle_wire_2d(pos, x, y, radius, 40);
+ }
+
+ /* Outer Ring: Dark color for contrast on light backgrounds (e.g. gray on white) */
+ mul_v3_v3fl(darkcolor, color, 0.40f);
+ immUniformColor4f(darkcolor[0], darkcolor[1], darkcolor[2], 0.8f);
+ imm_draw_circle_wire_2d(pos, x, y, radius + 1, 40);
+
+ glDisable(GL_BLEND);
+ glDisable(GL_LINE_SMOOTH);
+
+ /* Draw line for lazy mouse */
+ if ((last_mouse_position) &&
+ (paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP))
+ {
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+
+ copy_v3_v3(color, paintbrush->add_col);
+ immUniformColor4f(color[0], color[1], color[2], 0.8f);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, x, y);
+ immVertex2f(
+ pos,
+ last_mouse_position[0] + ar->winrct.xmin,
+ last_mouse_position[1] + ar->winrct.ymin);
+ immEnd();
+
+ glDisable(GL_BLEND);
+ glDisable(GL_LINE_SMOOTH);
+ }
+
+ immUnbindProgram();
+}
+
+/* Turn brush cursor in on/off */
+void ED_gpencil_toggle_brush_cursor(bContext *C, bool enable, void *customdata)
+{
+ Scene *scene = CTX_data_scene(C);
+ GP_BrushEdit_Settings *gset = &scene->toolsettings->gp_sculpt;
+ int *lastpost = customdata;
+
+ if (gset->paintcursor && !enable) {
+ /* clear cursor */
+ WM_paint_cursor_end(CTX_wm_manager(C), gset->paintcursor);
+ gset->paintcursor = NULL;
+ }
+ else if (enable) {
+ /* in some situations cursor could be duplicated, so it is better disable first if exist */
+ if (gset->paintcursor) {
+ /* clear cursor */
+ WM_paint_cursor_end(CTX_wm_manager(C), gset->paintcursor);
+ gset->paintcursor = NULL;
+ }
+ /* enable cursor */
+ gset->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C),
+ NULL,
+ gp_brush_drawcursor,
+ (lastpost) ? customdata : NULL);
+ }
+}
+
+/* verify if is using the right brush */
+static void gpencil_verify_brush_type(bContext *C, int newmode)
+{
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ GP_BrushEdit_Settings *gset = &ts->gp_sculpt;
+
+ switch (newmode) {
+ case OB_MODE_GPENCIL_SCULPT:
+ gset->flag &= ~GP_BRUSHEDIT_FLAG_WEIGHT_MODE;
+ if ((gset->brushtype < 0) || (gset->brushtype >= GP_EDITBRUSH_TYPE_WEIGHT)) {
+ gset->brushtype = GP_EDITBRUSH_TYPE_PUSH;
+ }
+ break;
+ case OB_MODE_GPENCIL_WEIGHT:
+ gset->flag |= GP_BRUSHEDIT_FLAG_WEIGHT_MODE;
+ if ((gset->weighttype < GP_EDITBRUSH_TYPE_WEIGHT) || (gset->weighttype >= TOT_GP_EDITBRUSH_TYPES)) {
+ gset->weighttype = GP_EDITBRUSH_TYPE_WEIGHT;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/* set object modes */
+void ED_gpencil_setup_modes(bContext *C, bGPdata *gpd, int newmode)
+{
+ if (!gpd) {
+ return;
+ }
+
+ switch (newmode) {
+ case OB_MODE_GPENCIL_EDIT:
+ gpd->flag |= GP_DATA_STROKE_EDITMODE;
+ gpd->flag &= ~GP_DATA_STROKE_PAINTMODE;
+ gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE;
+ gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE;
+ ED_gpencil_toggle_brush_cursor(C, false, NULL);
+ break;
+ case OB_MODE_GPENCIL_PAINT:
+ gpd->flag &= ~GP_DATA_STROKE_EDITMODE;
+ gpd->flag |= GP_DATA_STROKE_PAINTMODE;
+ gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE;
+ gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE;
+ ED_gpencil_toggle_brush_cursor(C, true, NULL);
+ break;
+ case OB_MODE_GPENCIL_SCULPT:
+ gpd->flag &= ~GP_DATA_STROKE_EDITMODE;
+ gpd->flag &= ~GP_DATA_STROKE_PAINTMODE;
+ gpd->flag |= GP_DATA_STROKE_SCULPTMODE;
+ gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE;
+ gpencil_verify_brush_type(C, OB_MODE_GPENCIL_SCULPT);
+ ED_gpencil_toggle_brush_cursor(C, true, NULL);
+ break;
+ case OB_MODE_GPENCIL_WEIGHT:
+ gpd->flag &= ~GP_DATA_STROKE_EDITMODE;
+ gpd->flag &= ~GP_DATA_STROKE_PAINTMODE;
+ gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE;
+ gpd->flag |= GP_DATA_STROKE_WEIGHTMODE;
+ gpencil_verify_brush_type(C, OB_MODE_GPENCIL_WEIGHT);
+ ED_gpencil_toggle_brush_cursor(C, true, NULL);
+ break;
+ default:
+ gpd->flag &= ~GP_DATA_STROKE_EDITMODE;
+ gpd->flag &= ~GP_DATA_STROKE_PAINTMODE;
+ gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE;
+ gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE;
+ ED_gpencil_toggle_brush_cursor(C, false, NULL);
+ break;
+ }
+}
+
+/* helper to convert 2d to 3d for simple drawing buffer */
+static void gpencil_stroke_convertcoords(ARegion *ar, const tGPspoint *point2D, float origin[3], float out[3])
+{
+ float mval_f[2] = { (float)point2D->x, (float)point2D->y };
+ float mval_prj[2];
+ float rvec[3], dvec[3];
+ float zfac;
+
+ copy_v3_v3(rvec, origin);
+
+ zfac = ED_view3d_calc_zfac(ar->regiondata, rvec, NULL);
+
+ if (ED_view3d_project_float_global(ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ sub_v2_v2v2(mval_f, mval_prj, mval_f);
+ ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
+ sub_v3_v3v3(out, rvec, dvec);
+ }
+ else {
+ zero_v3(out);
+ }
+}
+
+/* convert 2d tGPspoint to 3d bGPDspoint */
+void ED_gpencil_tpoint_to_point(ARegion *ar, float origin[3], const tGPspoint *tpt, bGPDspoint *pt)
+{
+ float p3d[3];
+ /* conversion to 3d format */
+ gpencil_stroke_convertcoords(ar, tpt, origin, p3d);
+ copy_v3_v3(&pt->x, p3d);
+
+ pt->pressure = tpt->pressure;
+ pt->strength = tpt->strength;
+ pt->uv_fac = tpt->uv_fac;
+ pt->uv_rot = tpt->uv_rot;
+}
+
+/* texture coordinate utilities */
+void ED_gpencil_calc_stroke_uv(Object *ob, bGPDstroke *gps)
+{
+ if (gps == NULL) {
+ return;
+ }
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
+ float pixsize;
+ if (gp_style) {
+ pixsize = gp_style->texture_pixsize / 1000000.0f;
+ }
+ else {
+ /* use this value by default */
+ pixsize = 0.000100f;
+ }
+ pixsize = MAX2(pixsize, 0.0000001f);
+
+ bGPDspoint *pt = NULL;
+ bGPDspoint *ptb = NULL;
+ int i;
+ float totlen = 0;
+
+ /* first read all points and calc distance */
+ for (i = 0; i < gps->totpoints; i++) {
+ pt = &gps->points[i];
+ /* first point */
+ if (i == 0) {
+ pt->uv_fac = 0.0f;
+ continue;
+ }
+
+ ptb = &gps->points[i - 1];
+ totlen += len_v3v3(&pt->x, &ptb->x) / pixsize;
+ pt->uv_fac = totlen;
+ }
+ /* normalize the distance using a factor */
+ float factor;
+ /* if image, use texture width */
+ if ((gp_style) && (gp_style->sima)) {
+ factor = gp_style->sima->gen_x;
+ }
+ else {
+ factor = totlen;
+ }
+ for (i = 0; i < gps->totpoints; i++) {
+ pt = &gps->points[i];
+ pt->uv_fac /= factor;
+ }
+}
+
+/* recalc uv for any stroke using the material */
+void ED_gpencil_update_color_uv(Main *bmain, Material *mat)
+{
+ Material *gps_ma = NULL;
+ /* read all strokes */
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->type == OB_GPENCIL) {
+ bGPdata *gpd = ob->data;
+ if (gpd == NULL) {
+ continue;
+ }
+
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ /* only editable and visible layers are considered */
+ if (gpencil_layer_is_editable(gpl)) {
+ for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* check if it is editable */
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ continue;
+ }
+ gps_ma = give_current_material(ob, gps->mat_nr + 1);
+ /* update */
+ if ((gps_ma) && (gps_ma == mat)) {
+ ED_gpencil_calc_stroke_uv(ob, gps);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
/* ******************************************************** */
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 59a54f03e56..ae86e4a5fbf 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -197,6 +197,8 @@ typedef enum eAnim_ChannelType {
ANIMTYPE_NLATRACK,
ANIMTYPE_NLAACTION,
+ ANIMTYPE_PALETTE,
+
/* always as last item, the total number of channel types... */
ANIMTYPE_NUM_TYPES
} eAnim_ChannelType;
@@ -347,6 +349,9 @@ typedef enum eAnimFilter_Flags {
/* Movie clip only */
#define EXPANDED_MCLIP(clip) (clip->flag & MCLIP_DATA_EXPAND)
+/* Palette only */
+#define EXPANDED_PALETTE(palette) (palette->flag & PALETTE_DATA_EXPAND)
+
/* AnimData - NLA mostly... */
#define SEL_ANIMDATA(adt) (adt->flag & ADT_UI_SELECTED)
diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h
index 7d509d1243a..333e3d72615 100644
--- a/source/blender/editors/include/ED_datafiles.h
+++ b/source/blender/editors/include/ED_datafiles.h
@@ -42,6 +42,9 @@ extern char datatoc_preview_blend[];
extern int datatoc_preview_cycles_blend_size;
extern char datatoc_preview_cycles_blend[];
+extern int datatoc_preview_grease_pencil_blend_size;
+extern char datatoc_preview_grease_pencil_blend[];
+
extern int datatoc_blender_icons16_png_size;
extern char datatoc_blender_icons16_png[];
@@ -239,6 +242,66 @@ extern char datatoc_mc23_jpg[];
extern int datatoc_mc24_jpg_size;
extern char datatoc_mc24_jpg[];
+/* grease pencil sculpt brushes files */
+
+extern int datatoc_gp_brush_smooth_png_size;
+extern char datatoc_gp_brush_smooth_png[];
+
+extern int datatoc_gp_brush_thickness_png_size;
+extern char datatoc_gp_brush_thickness_png[];
+
+extern int datatoc_gp_brush_strength_png_size;
+extern char datatoc_gp_brush_strength_png[];
+
+extern int datatoc_gp_brush_grab_png_size;
+extern char datatoc_gp_brush_grab_png[];
+
+extern int datatoc_gp_brush_push_png_size;
+extern char datatoc_gp_brush_push_png[];
+
+extern int datatoc_gp_brush_twist_png_size;
+extern char datatoc_gp_brush_twist_png[];
+
+extern int datatoc_gp_brush_pinch_png_size;
+extern char datatoc_gp_brush_pinch_png[];
+
+extern int datatoc_gp_brush_randomize_png_size;
+extern char datatoc_gp_brush_randomize_png[];
+
+extern int datatoc_gp_brush_clone_png_size;
+extern char datatoc_gp_brush_clone_png[];
+
+extern int datatoc_gp_brush_weight_png_size;
+extern char datatoc_gp_brush_weight_png[];
+
+extern int datatoc_gp_brush_pencil_png_size;
+extern char datatoc_gp_brush_pencil_png[];
+
+extern int datatoc_gp_brush_pen_png_size;
+extern char datatoc_gp_brush_pen_png[];
+
+extern int datatoc_gp_brush_ink_png_size;
+extern char datatoc_gp_brush_ink_png[];
+
+extern int datatoc_gp_brush_inknoise_png_size;
+extern char datatoc_gp_brush_inknoise_png[];
+
+extern int datatoc_gp_brush_block_png_size;
+extern char datatoc_gp_brush_block_png[];
+
+extern int datatoc_gp_brush_marker_png_size;
+extern char datatoc_gp_brush_marker_png[];
+
+extern int datatoc_gp_brush_fill_png_size;
+extern char datatoc_gp_brush_fill_png[];
+
+extern int datatoc_gp_brush_erase_soft_png_size;
+extern char datatoc_gp_brush_erase_soft_png[];
+
+extern int datatoc_gp_brush_erase_hard_png_size;
+extern char datatoc_gp_brush_erase_hard_png[];
+extern int datatoc_gp_brush_erase_stroke_png_size;
+extern char datatoc_gp_brush_erase_stroke_png[];
#endif /* __ED_DATAFILES_H__ */
diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h
index 39a58929b7c..41488baa964 100644
--- a/source/blender/editors/include/ED_gizmo_library.h
+++ b/source/blender/editors/include/ED_gizmo_library.h
@@ -40,7 +40,11 @@ void ED_gizmotypes_dial_3d(void);
void ED_gizmotypes_grab_3d(void);
void ED_gizmotypes_facemap_3d(void);
void ED_gizmotypes_primitive_3d(void);
+void ED_gizmotypes_blank_3d(void);
+struct bContext;
+struct Object;
+struct Scene;
struct wmGizmo;
struct wmGizmoGroup;
@@ -53,13 +57,13 @@ struct wmGizmoGroup;
/* gizmo_library_presets.c */
void ED_gizmo_draw_preset_box(
- const struct wmGizmo *mpr, float mat[4][4], int select_id);
+ const struct wmGizmo *gz, float mat[4][4], int select_id);
void ED_gizmo_draw_preset_arrow(
- const struct wmGizmo *mpr, float mat[4][4], int axis, int select_id);
+ const struct wmGizmo *gz, float mat[4][4], int axis, int select_id);
void ED_gizmo_draw_preset_circle(
- const struct wmGizmo *mpr, float mat[4][4], int axis, int select_id);
+ const struct wmGizmo *gz, float mat[4][4], int axis, int select_id);
void ED_gizmo_draw_preset_facemap(
- const struct bContext *C, const struct wmGizmo *mpr, struct Scene *scene,
+ const struct bContext *C, const struct wmGizmo *gz, struct Scene *scene,
struct Object *ob, const int facemap, int select_id);
@@ -87,8 +91,8 @@ enum {
ED_GIZMO_ARROW_DRAW_FLAG_STEM = (1 << 0),
};
-void ED_gizmo_arrow3d_set_ui_range(struct wmGizmo *mpr, const float min, const float max);
-void ED_gizmo_arrow3d_set_range_fac(struct wmGizmo *mpr, const float range_fac);
+void ED_gizmo_arrow3d_set_ui_range(struct wmGizmo *gz, const float min, const float max);
+void ED_gizmo_arrow3d_set_range_fac(struct wmGizmo *gz, const float range_fac);
/* -------------------------------------------------------------------- */
/* 2D Arrow Gizmo */
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index f1f2ce29e7f..13f8233079b 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -30,64 +30,44 @@
#ifndef __ED_GPENCIL_H__
#define __ED_GPENCIL_H__
-#include "ED_numinput.h"
-
struct ID;
struct ListBase;
-struct bContext;
-struct Depsgraph;
-struct ScrArea;
-struct ARegion;
-struct View3D;
-struct Object;
+struct PointerRNA;
+struct rcti;
+
struct bGPdata;
struct bGPDlayer;
struct bGPDframe;
struct bGPDstroke;
-struct bGPDpalette;
-struct bGPDpalettecolor;
-struct bAnimContext;
-struct KeyframeEditData;
-struct PointerRNA;
+struct bGPDspoint;
+struct Brush;
+
+struct Main;
+struct bContext;
+struct EvaluationContext;
+struct Depsgraph;
+struct ScrArea;
+struct ARegion;
+struct RegionView3D;
struct Scene;
+struct ToolSettings;
struct ViewLayer;
-struct wmWindowManager;
-struct wmKeyConfig;
-
-
-/* ------------- Grease-Pencil Helpers ---------------- */
-typedef struct tGPDinterpolate_layer {
- struct tGPDinterpolate_layer *next, *prev;
-
- struct bGPDlayer *gpl; /* layer */
- struct bGPDframe *prevFrame; /* frame before current frame (interpolate-from) */
- struct bGPDframe *nextFrame; /* frame after current frame (interpolate-to) */
- struct bGPDframe *interFrame; /* interpolated frame */
- float factor; /* interpolate factor */
+struct View3D;
-} tGPDinterpolate_layer;
+struct Object;
+struct Material;
-/* Temporary interpolate operation data */
-typedef struct tGPDinterpolate {
- struct Scene *scene; /* current scene from context */
- struct ScrArea *sa; /* area where painting originated */
- struct ARegion *ar; /* region where painting originated */
- struct bGPdata *gpd; /* current GP datablock */
+struct bAnimContext;
+struct KeyframeEditData;
- int cframe; /* current frame number */
- ListBase ilayers; /* (tGPDinterpolate_layer) layers to be interpolated */
- float shift; /* value for determining the displacement influence */
- float init_factor; /* initial interpolation factor for active layer */
- float low_limit; /* shift low limit (-100%) */
- float high_limit; /* shift upper limit (200%) */
- int flag; /* flag from toolsettings */
+struct wmKeyConfig;
+struct wmOperator;
+struct wmWindow;
+struct wmWindowManager;
- NumInput num; /* numeric input */
- void *draw_handle_3d; /* handle for drawing strokes while operator is running 3d stuff */
- void *draw_handle_screen; /* handle for drawing strokes while operator is running screen stuff */
-} tGPDinterpolate;
+/* ------------- Grease-Pencil Runtime Data ---------------- */
-/* Temporary 'Stroke Point' data
+/* Temporary 'Stroke Point' data (2D / screen-space)
*
* Used as part of the 'stroke cache' used during drawing of new strokes
*/
@@ -96,27 +76,43 @@ typedef struct tGPspoint {
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 */
} tGPspoint;
-
-/* Check if 'sketching sessions' are enabled */
-#define GPENCIL_SKETCH_SESSIONS_ON(scene) ((scene)->toolsettings->gpencil_flags & GP_TOOL_FLAG_PAINTSESSIONS_ON)
+/* used to sort by zdepth gpencil objects in viewport */
+/* TODO: this could be a system parameter in userprefs screen */
+#define GP_CACHE_BLOCK_SIZE 16
+typedef struct tGPencilSort {
+ struct Base *base;
+ float zdepth;
+} tGPencilSort;
/* ----------- Grease Pencil Tools/Context ------------- */
/* Context-dependent */
-struct bGPdata **ED_gpencil_data_get_pointers(const struct bContext *C, struct PointerRNA *ptr);
+struct bGPdata **ED_gpencil_data_get_pointers(const struct bContext *C, struct PointerRNA *r_ptr);
+
struct bGPdata *ED_gpencil_data_get_active(const struct bContext *C);
+struct bGPdata *ED_gpencil_data_get_active_evaluated(const struct bContext *C);
/* Context independent (i.e. each required part is passed in instead) */
-struct bGPdata **ED_gpencil_data_get_pointers_direct(struct ID *screen_id, struct Scene *scene,
- struct ScrArea *sa, struct Object *ob,
- struct PointerRNA *ptr);
-struct bGPdata *ED_gpencil_data_get_active_direct(struct ID *screen_id, struct Scene *scene,
- struct ScrArea *sa, struct Object *ob);
+struct bGPdata **ED_gpencil_data_get_pointers_direct(
+ struct ID *screen_id,
+ struct ScrArea *sa,
+ struct Scene *scene,
+ struct Object *ob,
+ struct PointerRNA *r_ptr);
+struct bGPdata *ED_gpencil_data_get_active_direct(
+ struct ID *screen_id,
+ struct ScrArea *sa,
+ struct Scene *scene,
+ struct Object *ob);
+
+bool ED_gpencil_data_owner_is_annotation(struct PointerRNA *owner_ptr);
/* 3D View */
-struct bGPdata *ED_gpencil_data_get_active_v3d(struct Scene *scene, struct ViewLayer *view_layer);
+struct bGPdata *ED_gpencil_data_get_active_v3d(struct ViewLayer *view_layer);
bool ED_gpencil_has_keyframe_v3d(struct Scene *scene, struct Object *ob, int cfra);
@@ -124,13 +120,7 @@ bool ED_gpencil_has_keyframe_v3d(struct Scene *scene, struct Object *ob, int cfr
bool ED_gpencil_stroke_can_use_direct(const struct ScrArea *sa, const struct bGPDstroke *gps);
bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke *gps);
-bool ED_gpencil_stroke_color_use(const struct bGPDlayer *gpl, const struct bGPDstroke *gps);
-
-struct bGPDpalettecolor *ED_gpencil_stroke_getcolor(struct bGPdata *gpd, struct bGPDstroke *gps);
-
-bool ED_gpencil_stroke_minmax(
- const struct bGPDstroke *gps, const bool use_select,
- float r_min[3], float r_max[3]);
+bool ED_gpencil_stroke_color_use(struct Object *ob, const struct bGPDlayer *gpl, const struct bGPDstroke *gps);
/* ----------- Grease Pencil Operators ----------------- */
@@ -150,16 +140,29 @@ void ED_gpencil_strokes_copybuf_free(void);
void ED_gpencil_draw_2dimage(const struct bContext *C);
void ED_gpencil_draw_view2d(const struct bContext *C, bool onlyv2d);
-void ED_gpencil_draw_view3d(struct wmWindowManager *wm,
- struct Scene *scene,
- struct ViewLayer *view_layer,
- struct Depsgraph *depsgraph,
- struct View3D *v3d,
- struct ARegion *ar,
- bool only3d);
-void ED_gpencil_draw_ex(struct Scene *scene, struct bGPdata *gpd, int winx, int winy,
- const int cfra, const char spacetype);
-void ED_gp_draw_interpolation(struct tGPDinterpolate *tgpi, const int type);
+void ED_gpencil_draw_view3d(
+ struct wmWindowManager *wm,
+ struct Scene *scene,
+ struct ViewLayer *view_layer,
+ struct Depsgraph *depsgraph,
+ struct View3D *v3d,
+ struct ARegion *ar,
+ bool only3d);
+void ED_gpencil_draw_view3d_annotations(
+ struct Scene *scene, struct Depsgraph *depsgraph,
+ struct View3D *v3d, struct ARegion *ar,
+ bool only3d);
+void ED_gpencil_draw_view3d_object(
+ struct wmWindowManager *wm,
+ struct Scene *scene,
+ struct Depsgraph *depsgraph,
+ struct Object *ob,
+ struct View3D *v3d,
+ struct ARegion *ar,
+ bool only3d);
+void ED_gpencil_draw_ex(
+ struct RegionView3D *rv3d, struct Scene *scene, struct bGPdata *gpd, int winx, int winy,
+ const int cfra, const char spacetype);
/* ----------- Grease-Pencil AnimEdit API ------------------ */
bool ED_gplayer_frames_looper(struct bGPDlayer *gpl, struct Scene *scene,
@@ -192,10 +195,46 @@ int ED_undo_gpencil_step(struct bContext *C, int step, const char *name);
/* ------------ Transformation Utilities ------------ */
-/* get difference matrix using parent */
-void ED_gpencil_parent_location(struct bGPDlayer *gpl, float diff_mat[4][4]);
+/* get difference matrix */
+void ED_gpencil_parent_location(
+ const struct Depsgraph *depsgraph, struct Object *obact, struct bGPdata *gpd,
+ struct bGPDlayer *gpl, float diff_mat[4][4]);
/* reset parent matrix for all layers */
-void ED_gpencil_reset_layers_parent(struct bGPdata *gpd);
+void ED_gpencil_reset_layers_parent(struct Depsgraph *depsgraph, struct Object *obact, struct bGPdata *gpd);
+
+/* cursor utilities */
+void ED_gpencil_brush_draw_eraser(struct Brush *brush, int x, int y);
+
+/* ----------- Add Primitive Utilities -------------- */
+
+void ED_gpencil_create_monkey(struct bContext *C, float mat[4][4]);
+void ED_gpencil_create_stroke(struct bContext *C, float mat[4][4]);
+
+/* ------------ Object Utilities ------------ */
+struct Object *ED_add_gpencil_object(struct bContext *C, struct Scene *scene, const float loc[3]);
+void ED_gpencil_add_defaults(struct bContext *C);
+/* set object modes */
+void ED_gpencil_setup_modes(struct bContext *C, struct bGPdata *gpd, int newmode);
+
+void ED_gp_project_stroke_to_plane(struct Object *ob, struct RegionView3D *rv3d, struct bGPDstroke *gps, const float origin[3], const int axis);
+void ED_gp_project_point_to_plane(struct Object *ob, struct RegionView3D *rv3d, const float origin[3], const int axis, struct bGPDspoint *pt);
+void ED_gp_get_drawing_reference(struct View3D *v3d, struct Scene *scene, struct Object *ob, struct bGPDlayer *gpl, char align_flag, float vec[3]);
+
+/* set sculpt cursor */
+void ED_gpencil_toggle_brush_cursor(struct bContext *C, bool enable, void *customdata);
+
+/* vertex groups */
+void ED_gpencil_vgroup_assign(struct bContext *C, struct Object *ob, float weight);
+void ED_gpencil_vgroup_remove(struct bContext *C, struct Object *ob);
+void ED_gpencil_vgroup_select(struct bContext *C, struct Object *ob);
+void ED_gpencil_vgroup_deselect(struct bContext *C, struct Object *ob);
+
+/* join objects */
+int ED_gpencil_join_objects_exec(struct bContext *C, struct wmOperator *op);
+/* texture coordinate utilities */
+void ED_gpencil_tpoint_to_point(struct ARegion *ar, float origin[3], const struct tGPspoint *tpt, struct bGPDspoint *pt);
+void ED_gpencil_calc_stroke_uv(struct Object *ob, struct bGPDstroke *gps);
+void ED_gpencil_update_color_uv(struct Main *bmain, struct Material *mat);
#endif /* __ED_GPENCIL_H__ */
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index 9b0b2c970b2..45a0680e0c1 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -42,6 +42,7 @@ struct bActionGroup;
struct Object;
struct ListBase;
struct bGPDlayer;
+struct Palette;
struct MaskLayer;
struct Scene;
struct View2D;
@@ -109,7 +110,7 @@ typedef enum eKeyframeShapeDrawOpts {
} eKeyframeShapeDrawOpts;
/* draw simple diamond-shape keyframe */
-/* caller should set up vertex format, bind GPU_SHADER_KEYFRAME_DIAMOND, immBegin(GWN_PRIM_POINTS, n), then call this n times */
+/* caller should set up vertex format, bind GPU_SHADER_KEYFRAME_DIAMOND, immBegin(GPU_PRIM_POINTS, n), then call this n times */
void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, short mode, float alpha,
unsigned int pos_id, unsigned int size_id, unsigned int color_id, unsigned int outline_color_id);
@@ -151,9 +152,11 @@ void scene_to_keylist(struct bDopeSheet *ads, struct Scene *sce, struct DLRBT_Tr
/* DopeSheet Summary */
void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks);
/* Grease Pencil datablock summary */
-void gpencil_to_keylist(struct bDopeSheet *ads, struct bGPdata *gpd, struct DLRBT_Tree *keys);
+void gpencil_to_keylist(struct bDopeSheet *ads, struct bGPdata *gpd, struct DLRBT_Tree *keys, const bool active);
/* Grease Pencil Layer */
void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys);
+/* Palette */
+void palette_to_keylist(struct bDopeSheet *ads, struct Palette *palette, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks);
/* Mask */
void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskLayer *masklay, struct DLRBT_Tree *keys);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 38545137740..a39523983ba 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -42,6 +42,7 @@ struct ID;
struct Main;
struct Menu;
struct ModifierData;
+struct ShaderFxData;
struct Object;
struct ReportList;
struct Scene;
@@ -112,6 +113,7 @@ void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap
void ED_keymap_proportional_maskmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap,
const bool do_connected);
+void ED_keymap_editmesh_elem_mode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_object_base_select(struct Base *base, eObjectSelect_Mode mode);
void ED_object_base_activate(struct bContext *C, struct Base *base);
@@ -260,6 +262,40 @@ bool ED_object_iter_other(
bool ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v);
+
+/* object_greasepencil_modifier.c */
+struct GpencilModifierData *ED_object_gpencil_modifier_add(
+ struct ReportList *reports, struct Main *bmain, struct Scene *scene,
+ struct Object *ob, const char *name, int type);
+bool ED_object_gpencil_modifier_remove(
+ struct ReportList *reports, struct Main *bmain,
+ struct Object *ob, struct GpencilModifierData *md);
+void ED_object_gpencil_modifier_clear(
+ struct Main *bmain, struct Object *ob);
+int ED_object_gpencil_modifier_move_down(
+ struct ReportList *reports, struct Object *ob, struct GpencilModifierData *md);
+int ED_object_gpencil_modifier_move_up(
+ struct ReportList *reports, struct Object *ob, struct GpencilModifierData *md);
+int ED_object_gpencil_modifier_apply(
+ struct Main *bmain, struct ReportList *reports, struct Depsgraph *depsgraph,
+ struct Object *ob, struct GpencilModifierData *md, int mode);
+int ED_object_gpencil_modifier_copy(
+ struct ReportList *reports, struct Object *ob, struct GpencilModifierData *md);
+
+/* object_shader_fx.c */
+struct ShaderFxData *ED_object_shaderfx_add(
+ struct ReportList *reports, struct Main *bmain, struct Scene *scene,
+ struct Object *ob, const char *name, int type);
+bool ED_object_shaderfx_remove(
+ struct ReportList *reports, struct Main *bmain,
+ struct Object *ob, struct ShaderFxData *fx);
+void ED_object_shaderfx_clear(
+ struct Main *bmain, struct Object *ob);
+int ED_object_shaderfx_move_down(
+ struct ReportList *reports, struct Object *ob, struct ShaderFxData *fx);
+int ED_object_shaderfx_move_up(
+ struct ReportList *reports, struct Object *ob, struct ShaderFxData *fx);
+
/* object_select.c */
void ED_object_select_linked_by_id(struct bContext *C, struct ID *id);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 914641c1add..2445cbdb16c 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -286,6 +286,7 @@ bool ED_operator_object_active_editable_font(struct bContext *C);
bool ED_operator_editmesh(struct bContext *C);
bool ED_operator_editmesh_view3d(struct bContext *C);
bool ED_operator_editmesh_region_view3d(struct bContext *C);
+bool ED_operator_editmesh_auto_smooth(struct bContext *C);
bool ED_operator_editarmature(struct bContext *C);
bool ED_operator_editcurve(struct bContext *C);
bool ED_operator_editcurve_3d(struct bContext *C);
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 80dea103f8c..a8e8b347da2 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -89,6 +89,7 @@ enum TfmMode {
TFM_VERT_SLIDE,
TFM_SEQ_SLIDE,
TFM_BONE_ENVELOPE_DIST,
+ TFM_NORMAL_ROTATION,
};
/* TRANSFORM CONTEXTS */
@@ -154,18 +155,19 @@ int BIF_countTransformOrientation(const struct bContext *C);
#define P_CENTER (1 << 12)
#define P_GPENCIL_EDIT (1 << 13)
#define P_CURSOR_EDIT (1 << 14)
+#define P_CLNOR_INVALIDATE (1 << 15)
void Transform_Properties(struct wmOperatorType *ot, int flags);
/* transform gizmos */
-void TRANSFORM_WGT_gizmo(struct wmGizmoGroupType *wgt);
-void VIEW3D_WGT_xform_cage(struct wmGizmoGroupType *wgt);
+void TRANSFORM_GGT_gizmo(struct wmGizmoGroupType *gzgt);
+void VIEW3D_GGT_xform_cage(struct wmGizmoGroupType *gzgt);
-bool ED_widgetgroup_gizmo2d_poll(const struct bContext *C, struct wmGizmoGroupType *wgt);
-void ED_widgetgroup_gizmo2d_setup(const struct bContext *C, struct wmGizmoGroup *mgroup);
-void ED_widgetgroup_gizmo2d_refresh(const struct bContext *C, struct wmGizmoGroup *mgroup);
-void ED_widgetgroup_gizmo2d_draw_prepare(const struct bContext *C, struct wmGizmoGroup *mgroup);
+bool ED_widgetgroup_gizmo2d_poll(const struct bContext *C, struct wmGizmoGroupType *gzgt);
+void ED_widgetgroup_gizmo2d_setup(const struct bContext *C, struct wmGizmoGroup *gzgroup);
+void ED_widgetgroup_gizmo2d_refresh(const struct bContext *C, struct wmGizmoGroup *gzgroup);
+void ED_widgetgroup_gizmo2d_draw_prepare(const struct bContext *C, struct wmGizmoGroup *gzgroup);
/* Snapping */
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index efcf5978968..6b0c59fb557 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -119,7 +119,7 @@ void ED_view3d_cursor3d_position_rotation(
float cursor_co[3], float cursor_quat[4]);
void ED_view3d_cursor3d_update(
struct bContext *C, const int mval[2],
- bool use_depth, enum eV3DCursorOrient orientation);
+ const bool use_depth, enum eV3DCursorOrient orientation);
struct Camera *ED_view3d_camera_data_get(struct View3D *v3d, struct RegionView3D *rv3d);
@@ -523,7 +523,7 @@ void ED_view3d_stop_render_preview(struct wmWindowManager *wm, struct ARegion *a
void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa);
#define V3D_IS_ZBUF(v3d) \
- (((v3d)->flag & V3D_ZBUF_SELECT) && ((v3d)->drawtype > OB_WIRE))
+ (((v3d)->flag & V3D_ZBUF_SELECT) && ((v3d)->shading.type > OB_WIRE))
void ED_view3d_id_remap(struct View3D *v3d, const struct ID *old_id, struct ID *new_id);
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index ec4c7dddd4c..dec02faf85c 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -1001,6 +1001,30 @@ DEF_ICON(MATCAP_22)
DEF_ICON(MATCAP_23)
DEF_ICON(MATCAP_24)
+/* grease pencil sculpt */
+DEF_ICON(GPBRUSH_SMOOTH)
+DEF_ICON(GPBRUSH_THICKNESS)
+DEF_ICON(GPBRUSH_STRENGTH)
+DEF_ICON(GPBRUSH_GRAB)
+DEF_ICON(GPBRUSH_PUSH)
+DEF_ICON(GPBRUSH_TWIST)
+DEF_ICON(GPBRUSH_PINCH)
+DEF_ICON(GPBRUSH_RANDOMIZE)
+DEF_ICON(GPBRUSH_CLONE)
+DEF_ICON(GPBRUSH_WEIGHT)
+
+DEF_ICON(GPBRUSH_PENCIL)
+DEF_ICON(GPBRUSH_PEN)
+DEF_ICON(GPBRUSH_INK)
+DEF_ICON(GPBRUSH_INKNOISE)
+DEF_ICON(GPBRUSH_BLOCK)
+DEF_ICON(GPBRUSH_MARKER)
+DEF_ICON(GPBRUSH_CUSTOM)
+DEF_ICON(GPBRUSH_FILL)
+DEF_ICON(GPBRUSH_ERASE_SOFT)
+DEF_ICON(GPBRUSH_ERASE_HARD)
+DEF_ICON(GPBRUSH_ERASE_STROKE)
+
/* vector icons, VICO_ prefix added */
DEF_VICO(SMALL_TRI_RIGHT_VEC)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 723dde640e4..824920bce73 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -772,7 +772,7 @@ typedef enum {
uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2);
eAutoPropButsReturn uiDefAutoButsRNA(
uiLayout *layout, struct PointerRNA *ptr,
- bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
+ bool (*check_prop)(struct PointerRNA *ptr, struct PropertyRNA *prop, void *user_data), void *user_data,
eButLabelAlign label_align, const bool compact);
/* use inside searchfunc to add items */
@@ -935,6 +935,7 @@ enum {
UI_TEMPLATE_OP_PROPS_SHOW_TITLE = (1 << 0),
UI_TEMPLATE_OP_PROPS_SHOW_EMPTY = (1 << 1),
UI_TEMPLATE_OP_PROPS_COMPACT = (1 << 2),
+ UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED = (1 << 3),
};
/* used for transp checkers */
@@ -1021,7 +1022,8 @@ uiLayout *uiLayoutRadial(uiLayout *layout);
void uiTemplateHeader(uiLayout *layout, struct bContext *C);
void uiTemplateID(
uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname,
- const char *newop, const char *openop, const char *unlinkop, int filter);
+ const char *newop, const char *openop, const char *unlinkop,
+ int filter, const bool live_icon);
void uiTemplateIDBrowse(
uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname,
const char *newop, const char *openop, const char *unlinkop, int filter);
@@ -1051,6 +1053,12 @@ void uiTemplatePathBuilder(
uiLayout *layout, struct PointerRNA *ptr, const char *propname,
struct PointerRNA *root_ptr, const char *text);
uiLayout *uiTemplateModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
+uiLayout *uiTemplateGpencilModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
+void uiTemplateGpencilColorPreview(
+ uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname,
+ int rows, int cols, float scale, int filter);
+
+uiLayout *uiTemplateShaderFx(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
void uiTemplateOperatorRedoProperties(uiLayout *layout, const struct bContext *C);
@@ -1069,6 +1077,7 @@ void uiTemplateCurveMapping(
bool levels, bool brush, bool neg_slope);
void uiTemplateColorPicker(uiLayout *layout, struct PointerRNA *ptr, const char *propname, bool value_slider, bool lock, bool lock_luminosity, bool cubic);
void uiTemplatePalette(uiLayout *layout, struct PointerRNA *ptr, const char *propname, bool color);
+void uiTemplateCryptoPicker(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
void uiTemplateLayers(
uiLayout *layout, struct PointerRNA *ptr, const char *propname,
PointerRNA *used_ptr, const char *used_propname, int active_layer);
@@ -1084,7 +1093,6 @@ void UI_but_func_operator_search(uiBut *but);
void uiTemplateOperatorSearch(uiLayout *layout);
eAutoPropButsReturn uiTemplateOperatorPropertyButs(
const struct bContext *C, uiLayout *layout, struct wmOperator *op,
- bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
const eButLabelAlign label_align, const short flag);
void uiTemplateHeader3D_mode(uiLayout *layout, struct bContext *C);
void uiTemplateHeader3D(uiLayout *layout, struct bContext *C);
@@ -1193,7 +1201,7 @@ void ED_operatortypes_ui(void);
void ED_keymap_ui(struct wmKeyConfig *keyconf);
void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop);
-bool UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event);
+bool UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event, const char **tooltip);
bool UI_context_copy_to_selected_list(
struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
@@ -1265,7 +1273,7 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p);
/* ui_interface_region_tooltip.c */
struct ARegion *UI_tooltip_create_from_button(struct bContext *C, struct ARegion *butregion, uiBut *but);
-struct ARegion *UI_tooltip_create_from_gizmo(struct bContext *C, struct wmGizmo *mpr);
+struct ARegion *UI_tooltip_create_from_gizmo(struct bContext *C, struct wmGizmo *gz);
void UI_tooltip_free(struct bContext *C, struct bScreen *sc, struct ARegion *ar);
/* How long before a tool-tip shows. */
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 651081c46bb..a34c4938b86 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -59,7 +59,7 @@ typedef struct IconFile {
/*
* Resizable Icons for Blender
*/
-void UI_icons_init(int first_dyn_id);
+void UI_icons_init(void);
int UI_icon_get_width(int icon_id);
int UI_icon_get_height(int icon_id);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 3e01c5f356f..37c56d454bb 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -280,7 +280,7 @@ static void ui_update_window_matrix(const wmWindow *window, const ARegion *regio
/* window matrix and aspect */
if (region && region->visible) {
/* Get projection matrix which includes View2D translation and zoom. */
- gpuGetProjectionMatrix(block->winmat);
+ GPU_matrix_projection_get(block->winmat);
block->aspect = 2.0f / fabsf(region->winx * block->winmat[0][0]);
}
else {
@@ -1448,9 +1448,9 @@ void UI_block_draw(const bContext *C, uiBlock *block)
ui_but_to_pixelrect(&rect, ar, block, NULL);
/* pixel space for AA widgets */
- gpuPushProjectionMatrix();
- gpuPushMatrix();
- gpuLoadIdentity();
+ GPU_matrix_push_projection();
+ GPU_matrix_push();
+ GPU_matrix_identity_set();
wmOrtho2_region_pixelspace(ar);
@@ -1485,8 +1485,8 @@ void UI_block_draw(const bContext *C, uiBlock *block)
BLF_batch_draw_end();
/* restore matrix */
- gpuPopProjectionMatrix();
- gpuPopMatrix();
+ GPU_matrix_pop_projection();
+ GPU_matrix_pop();
}
static void ui_block_message_subscribe(ARegion *ar, struct wmMsgBus *mbus, uiBlock *block)
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 240649c8ab0..d00ab70562c 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -715,7 +715,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
}
/* Show header tools for header buttons. */
- if (ui_block_is_menu(but->block) == false) {
+ if (ui_block_is_popup_any(but->block) == false) {
ARegion *ar = CTX_wm_region(C);
if (ar && (ar->regiontype == RGN_TYPE_HEADER)) {
uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 51f2c7e8ece..6a304a8150e 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -130,19 +130,19 @@ void UI_draw_roundbox_aa(bool filled, float minx, float miny, float maxx, float
/* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
* If it has been scaled, then it's no longer valid. */
- Gwn_Batch *batch = ui_batch_roundbox_get(filled, true);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
- GWN_batch_draw(batch);
+ 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);
}
else {
/* plain antialiased unfilled box */
GPU_line_smooth(true);
- Gwn_Batch *batch = ui_batch_roundbox_get(filled, false);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
- GWN_batch_draw(batch);
+ 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);
GPU_line_smooth(false);
}
@@ -159,8 +159,8 @@ void UI_draw_roundbox_4fv(bool filled, float minx, float miny, float maxx, float
};
int a;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
/* mult */
for (a = 0; a < 7; a++) {
@@ -176,7 +176,7 @@ void UI_draw_roundbox_4fv(bool filled, float minx, float miny, float maxx, float
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(col);
- immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, vert_len);
+ immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_len);
/* start with corner right-bottom */
if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
immVertex2f(pos, maxx - rad, miny);
@@ -244,10 +244,10 @@ void UI_draw_roundbox_4fv(bool filled, float minx, float miny, float maxx, float
.alpha_discard = 1.0f,
};
- Gwn_Batch *batch = ui_batch_roundbox_get(filled, false);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
- GWN_batch_draw(batch);
+ 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);
}
#if 0
@@ -280,9 +280,9 @@ void UI_draw_roundbox_shade_x(
int vert_count = 0;
int a;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
@@ -304,7 +304,7 @@ void UI_draw_roundbox_shade_x(
vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
- immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, vert_count);
+ immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count);
/* start with corner right-bottom */
if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
@@ -404,10 +404,10 @@ void UI_draw_roundbox_shade_x(
.alpha_discard = 1.0f,
};
- Gwn_Batch *batch = ui_batch_roundbox_get(filled, false);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
- GWN_batch_draw(batch);
+ 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);
}
#if 0 /* unused */
@@ -432,9 +432,9 @@ void UI_draw_roundbox_shade_y(
mul_v2_fl(vec[a], rad);
}
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
@@ -452,7 +452,7 @@ void UI_draw_roundbox_shade_y(
vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
- immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, vert_count);
+ immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count);
/* start with corner right-bottom */
if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
@@ -535,8 +535,8 @@ void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const flo
{
int ofs_y = 4 * U.pixelsize;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(color);
@@ -550,9 +550,9 @@ void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const flo
/* based on UI_draw_roundbox_gl_mode, check on making a version which allows us to skip some sides */
void ui_draw_but_TAB_outline(const rcti *rect, float rad, unsigned char highlight[3], unsigned char highlight_fade[3])
{
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
/* add a 1px offset, looks nicer */
const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize;
const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize;
@@ -571,7 +571,7 @@ void ui_draw_but_TAB_outline(const rcti *rect, float rad, unsigned char highligh
}
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- immBeginAtMost(GWN_PRIM_LINE_STRIP, 25);
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, 25);
immAttrib3ubv(col, highlight);
@@ -685,8 +685,8 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
*
* \Note This functionn is to be used with the 2D dashed shader enabled.
*
- * \param pos is a PRIM_FLOAT, 2, GWN_FETCH_FLOAT vertex attrib
- * \param line_origin is a PRIM_FLOAT, 2, GWN_FETCH_FLOAT vertex attrib
+ * \param pos is a PRIM_FLOAT, 2, GPU_FETCH_FLOAT vertex attrib
+ * \param line_origin is a PRIM_FLOAT, 2, GPU_FETCH_FLOAT vertex attrib
*
* The next 4 parameters are the offsets for the view, not the zones.
*/
@@ -749,7 +749,7 @@ static void histogram_draw_one(
/* curve outline */
GPU_line_width(1.5);
- immBegin(GWN_PRIM_LINE_STRIP, res);
+ immBegin(GPU_PRIM_LINE_STRIP, res);
for (int i = 0; i < res; i++) {
float x2 = x + i * (w / (float)res);
immVertex2f(pos_attrib, x2, y + (data[i] * h));
@@ -758,7 +758,7 @@ static void histogram_draw_one(
}
else {
/* under the curve */
- immBegin(GWN_PRIM_TRI_STRIP, res * 2);
+ immBegin(GPU_PRIM_TRI_STRIP, res * 2);
immVertex2f(pos_attrib, x, y);
immVertex2f(pos_attrib, x, y + (data[0] * h));
for (int i = 1; i < res; i++) {
@@ -772,7 +772,7 @@ static void histogram_draw_one(
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f);
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- immBegin(GWN_PRIM_LINE_STRIP, res);
+ immBegin(GPU_PRIM_LINE_STRIP, res);
for (int i = 0; i < res; i++) {
float x2 = x + i * (w / (float)res);
immVertex2f(pos_attrib, x2, y + (data[i] * h));
@@ -818,8 +818,8 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUS
(rect.xmax + 1) - (rect.xmin - 1),
(rect.ymax + 1) - (rect.ymin - 1));
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -833,7 +833,7 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUS
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
}
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, rect.xmin, rect.ymin + fac * h);
immVertex2f(pos, rect.xmax, rect.ymin + fac * h);
@@ -869,21 +869,21 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUS
static void waveform_draw_one(float *waveform, int nbr, const float col[3])
{
- Gwn_VertFormat format = {0};
- uint pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat format = {0};
+ uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, nbr);
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, nbr);
- GWN_vertbuf_attr_fill(vbo, pos_id, waveform);
+ GPU_vertbuf_attr_fill(vbo, pos_id, waveform);
- /* TODO store the Gwn_Batch inside the scope */
- Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
- GWN_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f);
- GWN_batch_draw(batch);
+ /* TODO store the GPUBatch inside the scope */
+ GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
+ GPU_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f);
+ GPU_batch_draw(batch);
- GWN_batch_discard(batch);
+ GPU_batch_discard(batch);
}
void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
@@ -957,15 +957,15 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE
GPU_blend(true);
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
/* draw grid lines here */
- immBegin(GWN_PRIM_LINES, 12);
+ immBegin(GPU_PRIM_LINES, 12);
for (int i = 0; i < 6; i++) {
immVertex2f(pos, rect.xmin + 22, yofs + (i * 0.2f) * h);
@@ -976,7 +976,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE
/* 3 vertical separation */
if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
for (int i = 1; i < 3; i++) {
immVertex2f(pos, rect.xmin + i * w3, rect.ymin);
@@ -987,7 +987,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE
}
/* separate min max zone on the right */
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, rect.xmin + w, rect.ymin);
immVertex2f(pos, rect.xmin + w, rect.ymax);
immEnd();
@@ -995,7 +995,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE
/* 16-235-240 level in case of ITU-R BT601/709 */
immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709)) {
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
immVertex2f(pos, rect.xmin + 22, yofs + h * 16.0f / 255.0f);
immVertex2f(pos, rect.xmax + 1, yofs + h * 16.0f / 255.0f);
@@ -1013,7 +1013,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE
}
/* 7.5 IRE black point level for NTSC */
if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, rect.xmin, yofs + h * 0.075f);
immVertex2f(pos, rect.xmax + 1, yofs + h * 0.075f);
immEnd();
@@ -1027,13 +1027,13 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE
if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
float col[3] = {alpha, alpha, alpha};
- gpuPushMatrix();
- gpuTranslate2f(rect.xmin, yofs);
- gpuScale2f(w, h);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(rect.xmin, yofs);
+ GPU_matrix_scale_2f(w, h);
waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, col);
- gpuPopMatrix();
+ GPU_matrix_pop();
/* min max */
immUniformColor3f(0.5f, 0.5f, 0.5f);
@@ -1042,22 +1042,22 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE
CLAMP(min, rect.ymin, rect.ymax);
CLAMP(max, rect.ymin, rect.ymax);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, rect.xmax - 3, min);
immVertex2f(pos, rect.xmax - 3, max);
immEnd();
}
/* RGB (3 channel) */
else if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB) {
- gpuPushMatrix();
- gpuTranslate2f(rect.xmin, yofs);
- gpuScale2f(w, h);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(rect.xmin, yofs);
+ GPU_matrix_scale_2f(w, h);
waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, colors_alpha[0]);
waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, colors_alpha[1]);
waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, colors_alpha[2]);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
/* PARADE / YCC (3 channels) */
else if (ELEM(scopes->wavefrm_mode,
@@ -1069,19 +1069,19 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE
{
int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB_PARADE);
- gpuPushMatrix();
- gpuTranslate2f(rect.xmin, yofs);
- gpuScale2f(w3, h);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(rect.xmin, yofs);
+ GPU_matrix_scale_2f(w3, h);
waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, (rgb) ? colors_alpha[0] : colorsycc_alpha[0]);
- gpuTranslate2f(1.0f, 0.0f);
+ GPU_matrix_translate_2f(1.0f, 0.0f);
waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, (rgb) ? colors_alpha[1] : colorsycc_alpha[1]);
- gpuTranslate2f(1.0f, 0.0f);
+ GPU_matrix_translate_2f(1.0f, 0.0f);
waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, (rgb) ? colors_alpha[2] : colorsycc_alpha[2]);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
/* min max */
@@ -1096,7 +1096,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE
CLAMP(min, rect.ymin, rect.ymax);
CLAMP(max, rect.ymin, rect.ymax);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, rect.xmin + w + 2 + c * 2, min);
immVertex2f(pos, rect.xmin + w + 2 + c * 2, max);
immEnd();
@@ -1140,7 +1140,7 @@ static void vectorscope_draw_target(unsigned int pos, float centerx, float cente
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f);
dangle = DEG2RADF(2.5f);
dampli = 2.5f / 200.0f;
- immBegin(GWN_PRIM_LINE_LOOP, 4);
+ immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
@@ -1152,22 +1152,22 @@ static void vectorscope_draw_target(unsigned int pos, float centerx, float cente
dampli = 0.2f * tampli;
dangle2 = DEG2RADF(5.0f);
dampli2 = 0.5f * dampli;
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle + dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle + dangle));
immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli + dampli, tangle + dangle - dangle2));
immEnd();
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle + dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle + dangle));
immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli - dampli, tangle + dangle - dangle2));
immEnd();
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle - dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle - dangle));
immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli - dampli, tangle - dangle + dangle2));
immEnd();
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle - dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle - dangle));
immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli + dampli, tangle - dangle + dangle2));
@@ -1215,15 +1215,15 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UN
(rect.xmax + 1) - (rect.xmin - 1),
(rect.ymax + 1) - (rect.ymin - 1));
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
/* draw grid elements */
/* cross */
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, centerx - (diam * 0.5f) - 5, centery);
immVertex2f(pos, centerx + (diam * 0.5f) + 5, centery);
@@ -1236,7 +1236,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UN
/* circles */
for (int j = 0; j < 5; j++) {
const int increment = 15;
- immBegin(GWN_PRIM_LINE_LOOP, (int)(360 / increment));
+ immBegin(GPU_PRIM_LINE_LOOP, (int)(360 / increment));
for (int i = 0; i <= 360 - increment; i += increment) {
const float a = DEG2RADF((float)i);
const float r = (j + 1) * 0.1f;
@@ -1247,7 +1247,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UN
/* skin tone line */
immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5f, skin_rad));
immVertex2f(pos, polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1f, skin_rad));
immEnd();
@@ -1263,13 +1263,13 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UN
glBlendFunc(GL_ONE, GL_ONE);
GPU_point_size(1.0);
- gpuPushMatrix();
- gpuTranslate2f(centerx, centery);
- gpuScaleUniform(diam);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(centerx, centery);
+ GPU_matrix_scale_1f(diam);
waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
immUnbindProgram();
@@ -1284,7 +1284,7 @@ static void ui_draw_colorband_handle_tri_hlight(unsigned int pos, float x1, floa
{
GPU_line_smooth(true);
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos, x1 + halfwidth, y1);
immVertex2f(pos, x1, y1 + height);
immVertex2f(pos, x1 - halfwidth, y1);
@@ -1297,7 +1297,7 @@ static void ui_draw_colorband_handle_tri(unsigned int pos, float x1, float y1, f
{
glEnable(fill ? GL_POLYGON_SMOOTH : GL_LINE_SMOOTH);
- immBegin(fill ? GWN_PRIM_TRIS : GWN_PRIM_LINE_LOOP, 3);
+ immBegin(fill ? GPU_PRIM_TRIS : GPU_PRIM_LINE_LOOP, 3);
immVertex2f(pos, x1 + halfwidth, y1);
immVertex2f(pos, x1, y1 + height);
immVertex2f(pos, x1 - halfwidth, y1);
@@ -1308,7 +1308,7 @@ static void ui_draw_colorband_handle_tri(unsigned int pos, float x1, float y1, f
static void ui_draw_colorband_handle_box(unsigned int pos, float x1, float y1, float x2, float y2, bool fill)
{
- immBegin(fill ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, 4);
+ immBegin(fill ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, 4);
immVertex2f(pos, x1, y1);
immVertex2f(pos, x1, y2);
immVertex2f(pos, x2, y2);
@@ -1348,7 +1348,7 @@ static void ui_draw_colorband_handle(
immUniformArray4fv("colors", (float *)(float[][4]){{0.8f, 0.8f, 0.8f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2);
immUniform1f("dash_width", active ? 4.0f : 2.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(shdr_pos, x, y1);
immVertex2f(shdr_pos, x, y2);
immEnd();
@@ -1419,8 +1419,8 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
float sizey_solid = sizey * 0.25f;
float y1 = rect->ymin;
- Gwn_VertFormat *format = immVertexFormat();
- pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_CHECKER);
/* Drawing the checkerboard. */
@@ -1432,8 +1432,8 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
/* New format */
format = immVertexFormat();
- pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- col_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ col_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
/* layer: color ramp */
@@ -1447,7 +1447,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
v1[1] = y1 + sizey_solid;
v2[1] = rect->ymax;
- immBegin(GWN_PRIM_TRI_STRIP, (sizex + 1) * 2);
+ immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
for (int a = 0; a <= sizex; a++) {
float pos = ((float)a) / sizex;
BKE_colorband_evaluate(coba, pos, colf);
@@ -1466,7 +1466,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
v1[1] = y1;
v2[1] = y1 + sizey_solid;
- immBegin(GWN_PRIM_TRI_STRIP, (sizex + 1) * 2);
+ immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
for (int a = 0; a <= sizex; a++) {
float pos = ((float)a) / sizex;
BKE_colorband_evaluate(coba, pos, colf);
@@ -1487,7 +1487,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
/* New format */
format = immVertexFormat();
- pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* layer: box outline */
@@ -1498,14 +1498,14 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
GPU_blend(true);
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos_id, x1, y1);
immVertex2f(pos_id, x1 + sizex, y1);
immEnd();
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.25f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos_id, x1, y1 - 1);
immVertex2f(pos_id, x1 + sizex, y1 - 1);
immEnd();
@@ -1548,28 +1548,28 @@ void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
ui_but_v3_get(but, light);
/* transform to button */
- gpuPushMatrix();
+ GPU_matrix_push();
if (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect))
size = 0.5f * BLI_rcti_size_x(rect);
else
size = 0.5f * BLI_rcti_size_y(rect);
- gpuTranslate2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect));
- gpuScaleUniform(size);
+ GPU_matrix_translate_2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect));
+ GPU_matrix_scale_1f(size);
- Gwn_Batch *sphere = GPU_batch_preset_sphere(2);
- GWN_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING);
- GWN_batch_uniform_4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.0f);
- GWN_batch_uniform_3fv(sphere, "light", light);
- GWN_batch_draw(sphere);
+ GPUBatch *sphere = GPU_batch_preset_sphere(2);
+ GPU_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING);
+ GPU_batch_uniform_4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.0f);
+ GPU_batch_uniform_3fv(sphere, "light", light);
+ GPU_batch_draw(sphere);
/* restore */
glDisable(GL_CULL_FACE);
/* AA circle */
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3ubv((unsigned char *)wcol->inner);
@@ -1580,7 +1580,7 @@ void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
GPU_line_smooth(false);
/* matrix after circle */
- gpuPopMatrix();
+ GPU_matrix_pop();
immUnbindProgram();
}
@@ -1599,7 +1599,7 @@ static void ui_draw_but_curve_grid(unsigned int pos, const rcti *rect, float zoo
floorf((rect->xmax - fx) / dx) + 1.0f +
floorf((rect->ymax - fy) / dy) + 1.0f);
- immBegin(GWN_PRIM_LINES, (int)line_count * 2);
+ immBegin(GPU_PRIM_LINES, (int)line_count * 2);
while (fx < rect->xmax) {
immVertex2f(pos, fx, rect->ymin);
immVertex2f(pos, fx, rect->ymax);
@@ -1675,8 +1675,8 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
GPU_line_width(1.0f);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* backdrop */
@@ -1712,7 +1712,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
/* axes */
gl_shaded_color((unsigned char *)wcol->inner, -50);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, rect->xmin, rect->ymin + zoomy * (-offsy));
immVertex2f(pos, rect->xmax, rect->ymin + zoomy * (-offsy));
immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymin);
@@ -1725,7 +1725,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
#if 0
if (cumap->flag & CUMA_DRAW_CFRA) {
immUniformColor3ub(0x60, 0xc0, 0x40);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin);
immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax);
immEnd();
@@ -1734,7 +1734,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
/* sample option */
if (cumap->flag & CUMA_DRAW_SAMPLE) {
- immBegin(GWN_PRIM_LINES, 2); /* will draw one of the following 3 lines */
+ immBegin(GPU_PRIM_LINES, 2); /* will draw one of the following 3 lines */
if (but->a1 == UI_GRAD_H) {
float tsample[3];
float hsv[3];
@@ -1770,7 +1770,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
immUniformColor3ubv((unsigned char *)wcol->item);
GPU_line_smooth(true);
GPU_blend(true);
- immBegin(GWN_PRIM_LINE_STRIP, (CM_TABLE + 1) + 2);
+ immBegin(GPU_PRIM_LINE_STRIP, (CM_TABLE + 1) + 2);
if (cuma->table == NULL)
curvemapping_changed(cumap, false);
@@ -1807,13 +1807,13 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
/* the points, use aspect to make them visible on edges */
format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
cmp = cuma->curve;
GPU_point_size(3.0f);
- immBegin(GWN_PRIM_POINTS, cuma->totpoint);
+ immBegin(GPU_PRIM_POINTS, cuma->totpoint);
for (int a = 0; a < cuma->totpoint; a++) {
float color[4];
if (cmp[a].flag & CUMA_SELECT)
@@ -1833,7 +1833,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
/* outline */
format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3ubv((unsigned char *)wcol->outline);
@@ -1900,7 +1900,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *U
}
if (!ok && scopes->track_preview) {
- gpuPushMatrix();
+ GPU_matrix_push();
/* draw content of pattern area */
GPU_scissor(rect.xmin, rect.ymin, scissor[2], scissor[3]);
@@ -1919,23 +1919,23 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *U
immDrawPixelsTex(&state, rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, drawibuf->rect, 1.0f, 1.0f, NULL);
/* draw cross for pixel position */
- gpuTranslate2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]);
+ GPU_matrix_translate_2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]);
GPU_scissor(
rect.xmin,
rect.ymin,
BLI_rctf_size_x(&rect),
BLI_rctf_size_y(&rect));
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
UI_GetThemeColor4fv(TH_SEL_MARKER, col_sel);
UI_GetThemeColor4fv(TH_MARKER_OUTLINE, col_outline);
/* Do stipple cross with geometry */
- immBegin(GWN_PRIM_LINES, 7 * 2 * 2);
+ immBegin(GPU_PRIM_LINES, 7 * 2 * 2);
float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f};
for (int axe = 0; axe < 2; ++axe) {
for (int i = 0; i < 7; ++i) {
@@ -1958,7 +1958,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *U
immUnbindProgram();
}
- gpuPopMatrix();
+ GPU_matrix_pop();
ok = true;
}
@@ -2018,13 +2018,13 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol
float x = 0.5f * (recti->xmin + recti->xmax);
float y = 0.5f * (recti->ymin + recti->ymax);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ubv(but->col);
GPU_blend(true);
- immBegin(GWN_PRIM_TRI_FAN, 16);
+ immBegin(GPU_PRIM_TRI_FAN, 16);
for (int a = 0; a < 16; a++)
immVertex2f(pos, x + size * si[a], y + size * co[a]);
immEnd();
@@ -2032,7 +2032,7 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol
immUniformColor4ub(0, 0, 0, 150);
GPU_line_width(1);
GPU_line_smooth(true);
- immBegin(GWN_PRIM_LINE_LOOP, 16);
+ immBegin(GPU_PRIM_LINE_LOOP, 16);
for (int a = 0; a < 16; a++)
immVertex2f(pos, x + size * si[a], y + size * co[a]);
immEnd();
@@ -2115,13 +2115,13 @@ void UI_draw_box_shadow(unsigned char alpha, float minx, float miny, float maxx,
{
GPU_blend(true);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- immBegin(GWN_PRIM_TRIS, 54);
+ immBegin(GPU_PRIM_TRIS, 54);
/* accumulated outline boxes to make shade not linear, is more pleasant */
ui_shadowbox(pos, color, minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8);
@@ -2186,11 +2186,11 @@ void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha
.alpha_discard = 1.0f,
};
- Gwn_Batch *batch = ui_batch_roundbox_shadow_get();
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW);
- GWN_batch_uniform_4fv_array(batch, "parameters", 4, (float *)&widget_params);
- GWN_batch_uniform_1f(batch, "alpha", 1.0f - visibility);
- GWN_batch_draw(batch);
+ GPUBatch *batch = ui_batch_roundbox_shadow_get();
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 4, (float *)&widget_params);
+ GPU_batch_uniform_1f(batch, "alpha", 1.0f - visibility);
+ GPU_batch_draw(batch);
/* outline emphasis */
GPU_line_smooth(true);
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index eb8fff471e2..424019995ad 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -82,6 +82,7 @@ wmKeyMap *eyedropper_modal_keymap(wmKeyConfig *keyconf)
/* assign to operators */
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_colorband");
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_color");
+ WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_color_crypto");
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_id");
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_depth");
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_driver");
diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c
index 73efc59feb7..bcce70d9d8a 100644
--- a/source/blender/editors/interface/interface_eyedropper_color.c
+++ b/source/blender/editors/interface/interface_eyedropper_color.c
@@ -36,6 +36,7 @@
#include "DNA_screen_types.h"
#include "BLI_math_vector.h"
+#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_main.h"
@@ -72,6 +73,8 @@ typedef struct Eyedropper {
bool accum_start; /* has mouse been pressed */
float accum_col[3];
int accum_tot;
+
+ bool accumulate; /* Color picking for cryptomatte, without accumulation. */
} Eyedropper;
static bool eyedropper_init(bContext *C, wmOperator *op)
@@ -80,6 +83,7 @@ static bool eyedropper_init(bContext *C, wmOperator *op)
Eyedropper *eye;
op->customdata = eye = MEM_callocN(sizeof(Eyedropper), "Eyedropper");
+ eye->accumulate = !STREQ(op->type->idname, "UI_OT_eyedropper_color_crypto");
UI_context_active_but_prop_get(C, &eye->ptr, &eye->prop, &eye->index);
@@ -207,29 +211,30 @@ static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3
RNA_property_update(C, &eye->ptr, eye->prop);
}
-/* set sample from accumulated values */
-static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye)
-{
- float col[3];
- mul_v3_v3fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot);
- eyedropper_color_set(C, eye, col);
-}
-
-/* single point sample & set */
static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my)
{
+ /* Accumulate color. */
float col[3];
eyedropper_color_sample_fl(C, mx, my, col);
- eyedropper_color_set(C, eye, col);
-}
-static void eyedropper_color_sample_accum(bContext *C, Eyedropper *eye, int mx, int my)
-{
- float col[3];
- eyedropper_color_sample_fl(C, mx, my, col);
- /* delay linear conversion */
- add_v3_v3(eye->accum_col, col);
- eye->accum_tot++;
+ if (eye->accumulate) {
+ add_v3_v3(eye->accum_col, col);
+ eye->accum_tot++;
+ }
+ else {
+ copy_v3_v3(eye->accum_col, col);
+ eye->accum_tot = 1;
+ }
+
+ /* Apply to property. */
+ float accum_col[3];
+ if (eye->accum_tot > 1) {
+ mul_v3_v3fl(accum_col, eye->accum_col, 1.0f / (float)eye->accum_tot);
+ }
+ else {
+ copy_v3_v3(accum_col, eye->accum_col);
+ }
+ eyedropper_color_set(C, eye, accum_col);
}
static void eyedropper_cancel(bContext *C, wmOperator *op)
@@ -254,29 +259,24 @@ static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (eye->accum_tot == 0) {
eyedropper_color_sample(C, eye, event->x, event->y);
}
- else {
- eyedropper_color_set_accum(C, eye);
- }
eyedropper_exit(C, op);
return OPERATOR_FINISHED;
case EYE_MODAL_SAMPLE_BEGIN:
/* enable accum and make first sample */
eye->accum_start = true;
- eyedropper_color_sample_accum(C, eye, event->x, event->y);
+ eyedropper_color_sample(C, eye, event->x, event->y);
break;
case EYE_MODAL_SAMPLE_RESET:
eye->accum_tot = 0;
zero_v3(eye->accum_col);
- eyedropper_color_sample_accum(C, eye, event->x, event->y);
- eyedropper_color_set_accum(C, eye);
+ eyedropper_color_sample(C, eye, event->x, event->y);
break;
}
}
- else if (event->type == MOUSEMOVE) {
+ else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
if (eye->accum_start) {
/* button is pressed so keep sampling */
- eyedropper_color_sample_accum(C, eye, event->x, event->y);
- eyedropper_color_set_accum(C, eye);
+ eyedropper_color_sample(C, eye, event->x, event->y);
}
}
@@ -297,7 +297,7 @@ static int eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
}
else {
eyedropper_exit(C, op);
- return OPERATOR_CANCELLED;
+ return OPERATOR_PASS_THROUGH;
}
}
@@ -315,26 +315,15 @@ static int eyedropper_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
else {
- return OPERATOR_CANCELLED;
+ return OPERATOR_PASS_THROUGH;
}
}
static bool eyedropper_poll(bContext *C)
{
- PointerRNA ptr;
- PropertyRNA *prop;
- int index_dummy;
- uiBut *but;
-
- /* Only color buttons */
- if ((CTX_wm_window(C) != NULL) &&
- (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) &&
- (but->type == UI_BTYPE_COLOR))
- {
- return 1;
- }
-
- return 0;
+ /* Actual test for active button happens later, since we don't
+ * know which one is active until mouse over. */
+ return (CTX_wm_window(C) != NULL);
}
void UI_OT_eyedropper_color(wmOperatorType *ot)
@@ -353,6 +342,22 @@ void UI_OT_eyedropper_color(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
+}
+
+void UI_OT_eyedropper_color_crypto(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Cryptomatte Eyedropper";
+ ot->idname = "UI_OT_eyedropper_color_crypto";
+ ot->description = "Pick a color from Cryptomatte node Pick output image";
- /* properties */
+ /* api callbacks */
+ ot->invoke = eyedropper_invoke;
+ ot->modal = eyedropper_modal;
+ ot->cancel = eyedropper_cancel;
+ ot->exec = eyedropper_exec;
+ ot->poll = eyedropper_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
}
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 62413e2434c..4f77b797ec0 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -47,6 +47,7 @@
#include "DNA_brush_types.h"
#include "DNA_curve_types.h"
#include "DNA_dynamicpaint_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -109,6 +110,7 @@ typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
#define ICON_TYPE_VECTOR 4
#define ICON_TYPE_GEOM 5
#define ICON_TYPE_EVENT 6 /* draw keymap entries using custom renderer. */
+#define ICON_TYPE_GPLAYER 7
typedef struct DrawInfo {
int type;
@@ -250,11 +252,11 @@ static void vicon_small_tri_right_draw(int x, int y, int w, int UNUSED(h), float
viconutil_set_point(pts[1], cx - d2, cy - d);
viconutil_set_point(pts[2], cx + d2, cy);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4f(0.2f, 0.2f, 0.2f, alpha);
- immBegin(GWN_PRIM_TRIS, 3);
+ immBegin(GPU_PRIM_TRIS, 3);
immVertex2iv(pos, pts[0]);
immVertex2iv(pos, pts[1]);
immVertex2iv(pos, pts[2]);
@@ -280,15 +282,15 @@ static void vicon_keytype_draw_wrapper(int x, int y, int w, int h, float alpha,
int xco = x + w / 2;
int yco = y + h / 2;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint size_id = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT);
- uint color_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
- uint outline_color_id = GWN_vertformat_attr_add(format, "outlineColor", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
GPU_enable_program_point_size();
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
/* draw keyframe
* - size: 0.6 * h (found out experimentally... dunno why!)
@@ -343,7 +345,7 @@ static void vicon_colorset_draw(int index, int x, int y, int w, int h, float UNU
const int b = x + w / 3 * 2;
const int c = x + w;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* XXX: Include alpha into this... */
@@ -391,6 +393,28 @@ DEF_VICON_COLORSET_DRAW_NTH(20, 19)
#undef DEF_VICON_COLORSET_DRAW_NTH
+/* Dynamically render icon instead of rendering a plain color to a texture/buffer
+ * This is mot strictly a "vicon", as it needs access to icon->obj to get the color info,
+ * but it works in a very similar way.
+ */
+static void vicon_gplayer_color_draw(Icon *icon, int x, int y, int w, int h)
+{
+ bGPDlayer *gpl = (bGPDlayer *)icon->obj;
+
+ /* Just draw a colored rect - Like for vicon_colorset_draw() */
+ /* TODO: Make this have rounded corners, and maybe be a bit smaller.
+ * However, UI_draw_roundbox_aa() draws the colors too dark, so can't be used.
+ */
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3fv(gpl->color);
+ immRecti(pos, x, y, x + w - 1, y + h - 1);
+
+ immUnbindProgram();
+}
+
+
#ifndef WITH_HEADLESS
static void init_brush_icons(void)
@@ -443,6 +467,30 @@ static void init_brush_icons(void)
INIT_BRUSH_ICON(ICON_BRUSH_ROTATE, twist);
INIT_BRUSH_ICON(ICON_BRUSH_VERTEXDRAW, vertexdraw);
+ /* grease pencil sculpt */
+ INIT_BRUSH_ICON(ICON_GPBRUSH_SMOOTH, gp_brush_smooth);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_THICKNESS, gp_brush_thickness);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_STRENGTH, gp_brush_strength);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_GRAB, gp_brush_grab);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_PUSH, gp_brush_push);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_TWIST, gp_brush_twist);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_PINCH, gp_brush_pinch);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_RANDOMIZE, gp_brush_randomize);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_CLONE, gp_brush_clone);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_WEIGHT, gp_brush_weight);
+
+ /* grease pencil drawing brushes */
+ INIT_BRUSH_ICON(ICON_GPBRUSH_PENCIL, gp_brush_pencil);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_PEN, gp_brush_pen);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_INK, gp_brush_ink);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_INKNOISE, gp_brush_inknoise);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_BLOCK, gp_brush_block);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_MARKER, gp_brush_marker);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_FILL, gp_brush_fill);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_SOFT, gp_brush_erase_soft);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_HARD, gp_brush_erase_hard);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_STROKE, gp_brush_erase_stroke);
+
#undef INIT_BRUSH_ICON
}
@@ -877,6 +925,9 @@ static DrawInfo *icon_create_drawinfo(Icon *icon)
else if (icon_data_type == ICON_DATA_STUDIOLIGHT) {
di->type = ICON_TYPE_BUFFER;
}
+ else if (icon_data_type == ICON_DATA_GPLAYER) {
+ di->type = ICON_TYPE_GPLAYER;
+ }
else {
BLI_assert(0);
}
@@ -934,9 +985,8 @@ int UI_icon_get_height(int icon_id)
return 0;
}
-void UI_icons_init(int first_dyn_id)
+void UI_icons_init()
{
- BKE_icons_init(first_dyn_id);
#ifndef WITH_HEADLESS
init_iconfile_list(&iconfilelist);
init_internal_icons();
@@ -1262,7 +1312,7 @@ static void icon_draw_cache_flush_ex(void)
glUniform1i(img_loc, 0);
glUniform4fv(data_loc, ICON_DRAW_CACHE_SIZE * 3, (float *)g_icon_draw_cache.drawcall_cache);
- GWN_draw_primitive(GWN_PRIM_TRIS, 6 * g_icon_draw_cache.calls);
+ GPU_draw_primitive(GPU_PRIM_TRIS, 6 * g_icon_draw_cache.calls);
glBindTexture(GL_TEXTURE_2D, 0);
@@ -1292,7 +1342,7 @@ static void icon_draw_texture_cached(
{
float mvp[4][4];
- gpuGetModelViewProjectionMatrix(mvp);
+ GPU_matrix_model_view_projection_get(mvp);
IconDrawCall *call = &g_icon_draw_cache.drawcall_cache[g_icon_draw_cache.calls];
g_icon_draw_cache.calls++;
@@ -1342,14 +1392,14 @@ static void icon_draw_texture(
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
GPU_shader_bind(shader);
- if (rgb) glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), rgb[0], rgb[1], rgb[2], alpha);
- else glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), alpha, alpha, alpha, alpha);
+ if (rgb) glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), rgb[0], rgb[1], rgb[2], alpha);
+ else glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), alpha, alpha, alpha, alpha);
glUniform1i(GPU_shader_get_uniform(shader, "image"), 0);
glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), x1, y1, x2, y2);
glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), x, y, x + w, y + h);
- GWN_draw_primitive(GWN_PRIM_TRI_STRIP, 4);
+ GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4);
glBindTexture(GL_TEXTURE_2D, 0);
}
@@ -1485,6 +1535,15 @@ static void icon_draw_size(
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
}
}
+ else if (di->type == ICON_TYPE_GPLAYER) {
+ BLI_assert(icon->obj != NULL);
+
+ /* We need to flush widget base first to ensure correct ordering. */
+ UI_widgetbase_draw_cache_flush();
+
+ /* Just draw a colored rect - Like for vicon_colorset_draw() */
+ vicon_gplayer_color_draw(icon, (int)x, (int)y, w, h);
+ }
}
static void ui_id_preview_image_render_size(
@@ -1577,7 +1636,45 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id)
}
/* reset the icon */
- if (mode == OB_MODE_SCULPT) {
+ if (ob->mode & OB_MODE_GPENCIL_PAINT) {
+ switch (br->gpencil_settings->icon_id) {
+ case GP_BRUSH_ICON_PENCIL:
+ br->id.icon_id = ICON_GPBRUSH_PENCIL;
+ break;
+ case GP_BRUSH_ICON_PEN:
+ br->id.icon_id = ICON_GPBRUSH_PEN;
+ break;
+ case GP_BRUSH_ICON_INK:
+ br->id.icon_id = ICON_GPBRUSH_INK;
+ break;
+ case GP_BRUSH_ICON_INKNOISE:
+ br->id.icon_id = ICON_GPBRUSH_INKNOISE;
+ break;
+ case GP_BRUSH_ICON_BLOCK:
+ br->id.icon_id = ICON_GPBRUSH_BLOCK;
+ break;
+ case GP_BRUSH_ICON_MARKER:
+ br->id.icon_id = ICON_GPBRUSH_MARKER;
+ break;
+ case GP_BRUSH_ICON_FILL:
+ br->id.icon_id = ICON_GPBRUSH_FILL;
+ break;
+ case GP_BRUSH_ICON_ERASE_SOFT:
+ br->id.icon_id = ICON_GPBRUSH_ERASE_SOFT;
+ break;
+ case GP_BRUSH_ICON_ERASE_HARD:
+ br->id.icon_id = ICON_GPBRUSH_ERASE_HARD;
+ break;
+ case GP_BRUSH_ICON_ERASE_STROKE:
+ br->id.icon_id = ICON_GPBRUSH_ERASE_STROKE;
+ break;
+ default:
+ br->id.icon_id = ICON_GPBRUSH_PEN;
+ break;
+ }
+ return id->icon_id;
+ }
+ else if (mode == OB_MODE_SCULPT) {
items = rna_enum_brush_sculpt_tool_items;
tool = br->sculpt_tool;
}
diff --git a/source/blender/editors/interface/interface_icons_event.c b/source/blender/editors/interface/interface_icons_event.c
index dc444b98b2c..fabf5f9bf48 100644
--- a/source/blender/editors/interface/interface_icons_event.c
+++ b/source/blender/editors/interface/interface_icons_event.c
@@ -136,8 +136,8 @@ static void icon_draw_rect_input_line_prim(
{
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- BLI_assert(ELEM(prim, GWN_PRIM_LINE_LOOP, GWN_PRIM_LINE_STRIP));
- const uint pos_id = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ BLI_assert(ELEM(prim, GPU_PRIM_LINE_LOOP, GPU_PRIM_LINE_STRIP));
+ const uint pos_id = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(color);
immBegin(prim, lines_len);
@@ -289,7 +289,7 @@ void icon_draw_rect_input(
else if (event_type == SPACEKEY) {
const uchar lines[] = {60, 118, 60, 60, 195, 60, 195, 118};
icon_draw_rect_input_line_prim(
- &rect, color, GWN_PRIM_LINE_STRIP,
+ &rect, color, GPU_PRIM_LINE_STRIP,
(const void *)lines, ARRAY_SIZE(lines) / 2);
}
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index ffc389c6dfd..f7507223f31 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -752,9 +752,9 @@ enum {
ROUNDBOX_TRIA_MAX, /* don't use */
};
-struct Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased);
-struct Gwn_Batch *ui_batch_roundbox_widget_get(int tria);
-struct Gwn_Batch *ui_batch_roundbox_shadow_get(void);
+struct GPUBatch *ui_batch_roundbox_get(bool filled, bool antialiased);
+struct GPUBatch *ui_batch_roundbox_widget_get(int tria);
+struct GPUBatch *ui_batch_roundbox_shadow_get(void);
void ui_draw_anti_tria_rect(const rctf *rect, char dir, const float color[4]);
void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect);
@@ -780,7 +780,7 @@ void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, const char *na
#define UI_POPUP_MENU_TOP (int)(8 * UI_DPI_FAC)
#define UI_PIXEL_AA_JITTER 8
-const float ui_pixel_jitter[UI_PIXEL_AA_JITTER][2];
+extern const float ui_pixel_jitter[UI_PIXEL_AA_JITTER][2];
/* interface_style.c */
void uiStyleInit(void);
@@ -831,7 +831,9 @@ bool ui_but_is_toggle(const uiBut *but);
bool ui_but_is_popover_once_compat(const uiBut *but);
extern bool ui_block_is_menu(const uiBlock *block) ATTR_WARN_UNUSED_RESULT;
+extern bool ui_block_is_popover(const uiBlock *block) ATTR_WARN_UNUSED_RESULT;
extern bool ui_block_is_pie_menu(const uiBlock *block) ATTR_WARN_UNUSED_RESULT;
+extern bool ui_block_is_popup_any(const uiBlock *block) ATTR_WARN_UNUSED_RESULT;
/* interface_context_menu.c */
bool ui_popup_context_menu_for_button(struct bContext *C, uiBut *but);
@@ -843,6 +845,7 @@ struct wmKeyMap *eyedropper_colorband_modal_keymap(struct wmKeyConfig *keyconf);
/* interface_eyedropper_color.c */
void UI_OT_eyedropper_color(struct wmOperatorType *ot);
+void UI_OT_eyedropper_color_crypto(struct wmOperatorType *ot);
/* interface_eyedropper_colorband.c */
void UI_OT_eyedropper_colorband(struct wmOperatorType *ot);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 82ed4c5acba..f143d418fe3 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1244,7 +1244,15 @@ void uiItemsFullEnumO(
bool free;
if (ui_layout_is_radial(layout)) {
+ /* XXX: While "_all()" guarantees spatial stability, it's bad when an enum has > 8 items total,
+ * but only a small subset will ever be shown at once (e.g. Mode Switch menu, after the
+ * introduction of GP editing modes)
+ */
+#if 0
RNA_property_enum_items_gettexted_all(block->evil_C, &ptr, prop, &item_array, &totitem, &free);
+#else
+ RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, &totitem, &free);
+#endif
}
else {
RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, &totitem, &free);
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 96128aa29f0..ae0fe912f95 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1243,7 +1243,7 @@ static void UI_OT_reloadtranslation(wmOperatorType *ot)
ot->exec = reloadtranslation_exec;
}
-bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
+bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
/* should only return true for regions that include buttons, for now
* return true always */
@@ -1359,6 +1359,7 @@ void ED_operatortypes_ui(void)
/* external */
WM_operatortype_append(UI_OT_eyedropper_color);
+ WM_operatortype_append(UI_OT_eyedropper_color_crypto);
WM_operatortype_append(UI_OT_eyedropper_colorband);
WM_operatortype_append(UI_OT_eyedropper_colorband_point);
WM_operatortype_append(UI_OT_eyedropper_id);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 79d92eedfa3..aa67d58fd57 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -454,9 +454,9 @@ static void ui_offset_panel_block(uiBlock *block)
/* triangle 'icon' for panel header */
void UI_draw_icon_tri(float x, float y, char dir, const float color[4])
{
- float f3 = 0.15 * U.widget_unit;
- float f5 = 0.25 * U.widget_unit;
- float f7 = 0.35 * U.widget_unit;
+ float f3 = 0.05 * U.widget_unit;
+ float f5 = 0.15 * U.widget_unit;
+ float f7 = 0.25 * U.widget_unit;
if (dir == 'h') {
UI_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y, color);
@@ -478,7 +478,7 @@ static void ui_draw_anti_x(unsigned int pos, float x1, float y1, float x2, float
GPU_line_width(2.0);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, x1, y1);
immVertex2f(pos, x2, y2);
@@ -519,7 +519,7 @@ static void ui_draw_panel_scalewidget(unsigned int pos, const rcti *rect)
GPU_blend(true);
immUniformColor4ub(255, 255, 255, 50);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, xmin, ymin);
immVertex2f(pos, xmax, ymax);
@@ -531,7 +531,7 @@ static void ui_draw_panel_scalewidget(unsigned int pos, const rcti *rect)
immUniformColor4ub(0, 0, 0, 50);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, xmin, ymin + 1);
immVertex2f(pos, xmax, ymax + 1);
@@ -584,7 +584,7 @@ static void ui_draw_panel_dragwidget(unsigned int pos, unsigned int col, const r
UI_GetThemeColorShade4fv(TH_PANEL_BACK, -col_tint, col_dark);
/* draw multiple boxes */
- immBegin(GWN_PRIM_TRIS, 4 * 2 * (6 * 2));
+ immBegin(GPU_PRIM_TRIS, 4 * 2 * (6 * 2));
for (i_x = 0; i_x < 4; i_x++) {
for (i_y = 0; i_y < 2; i_y++) {
const int x_co = (x_min + x_ofs) + (i_x * (box_size + box_margin));
@@ -677,7 +677,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
titlerect.xmin += 5.0f / block->aspect;
}
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
if (!is_subpanel) {
@@ -691,7 +691,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
immUniformThemeColor(TH_PANEL_HEADER);
immRectf(pos, minx, headrect.ymin, maxx, y);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, minx, y);
immVertex2f(pos, maxx, y);
@@ -729,9 +729,9 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
if (show_drag) {
uint col;
- Gwn_VertFormat *format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
/* itemrect smaller */
itemrect.xmax = headrect.xmax - 5.0f / block->aspect;
@@ -745,7 +745,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
immUnbindProgram();
/* Restore format for the following draws. */
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
}
}
@@ -758,7 +758,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
else if (is_closed_x) {
/* draw vertical title */
ui_draw_aligned_panel_header(style, block, &headrect, 'v');
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
}
/* an open panel */
else {
@@ -1700,9 +1700,9 @@ static void ui_panel_category_draw_tab(
{0.98, 0.805}};
int a;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
/* mult */
for (a = 0; a < 4; a++) {
@@ -1724,7 +1724,7 @@ static void ui_panel_category_draw_tab(
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_STRIP, vert_len);
+ immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_STRIP, vert_len);
/* start with corner right-top */
if (use_highlight) {
@@ -1929,7 +1929,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
/* begin drawing */
GPU_line_smooth(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* draw the background */
@@ -1991,7 +1991,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
/* tab blackline */
if (!is_active) {
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3ubv(theme_col_tab_divider);
@@ -2022,7 +2022,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
GPU_blend(false);
/* tab blackline remaining (last tab) */
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
if (pc_dyn->prev == NULL) {
immUniformColor3ubv(theme_col_tab_divider);
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index 66f63fef82d..d0f7e1341de 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -109,11 +109,25 @@ bool ui_block_is_menu(const uiBlock *block)
((block->flag & UI_BLOCK_KEEP_OPEN) == 0));
}
+bool ui_block_is_popover(const uiBlock *block)
+{
+ return (block->flag & UI_BLOCK_POPOVER) != 0;
+}
+
bool ui_block_is_pie_menu(const uiBlock *block)
{
return ((block->flag & UI_BLOCK_RADIAL) != 0);
}
+bool ui_block_is_popup_any(const uiBlock *block)
+{
+ return (
+ ui_block_is_menu(block) ||
+ ui_block_is_popover(block) ||
+ ui_block_is_pie_menu(block)
+ );
+}
+
bool UI_block_is_empty(const uiBlock *block)
{
for (const uiBut *but = block->buttons.first; but; but = but->next) {
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index fae547d460c..97f501b7448 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -615,7 +615,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
}
}
-static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *mpr)
+static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
{
uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
@@ -623,23 +623,23 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *mpr)
/* Operator Actions */
{
- bool use_drag = mpr->drag_part != -1 && mpr->highlight_part != mpr->drag_part;
+ bool use_drag = gz->drag_part != -1 && gz->highlight_part != gz->drag_part;
const struct {
int part;
const char *prefix;
} mpop_actions[] = {
{
- .part = mpr->highlight_part,
+ .part = gz->highlight_part,
.prefix = use_drag ? TIP_("Click") : NULL,
}, {
- .part = use_drag ? mpr->drag_part : -1,
+ .part = use_drag ? gz->drag_part : -1,
.prefix = use_drag ? TIP_("Drag") : NULL,
},
};
for (int i = 0; i < ARRAY_SIZE(mpop_actions); i++) {
- wmGizmoOpElem *mpop = (mpop_actions[i].part != -1) ? WM_gizmo_operator_get(mpr, mpop_actions[i].part) : NULL;
+ wmGizmoOpElem *mpop = (mpop_actions[i].part != -1) ? WM_gizmo_operator_get(gz, mpop_actions[i].part) : NULL;
if (mpop != NULL) {
/* Description */
const char *info = RNA_struct_ui_description(mpop->type->srna);
@@ -691,13 +691,13 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *mpr)
}
/* Property Actions */
- if (mpr->type->target_property_defs_len) {
- wmGizmoProperty *mpr_prop_array = WM_gizmo_target_property_array(mpr);
- for (int i = 0; i < mpr->type->target_property_defs_len; i++) {
+ if (gz->type->target_property_defs_len) {
+ wmGizmoProperty *gz_prop_array = WM_gizmo_target_property_array(gz);
+ for (int i = 0; i < gz->type->target_property_defs_len; i++) {
/* TODO(campbell): function callback descriptions. */
- wmGizmoProperty *mpr_prop = &mpr_prop_array[i];
- if (mpr_prop->prop != NULL) {
- const char *info = RNA_property_ui_description(mpr_prop->prop);
+ wmGizmoProperty *gz_prop = &gz_prop_array[i];
+ if (gz_prop->prop != NULL) {
+ const char *info = RNA_property_ui_description(gz_prop->prop);
if (info && info[0]) {
uiTooltipField *field = text_field_add(
data, &(uiTooltipFormat){
@@ -934,13 +934,13 @@ ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *b
return ui_tooltip_create_with_data(C, data, init_position, aspect);
}
-ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *mpr)
+ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz)
{
wmWindow *win = CTX_wm_window(C);
const float aspect = 1.0f;
float init_position[2];
- uiTooltipData *data = ui_tooltip_data_from_gizmo(C, mpr);
+ uiTooltipData *data = ui_tooltip_data_from_gizmo(C, gz);
if (data == NULL) {
return NULL;
}
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index 36ad516bf7f..ed4c766c596 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -522,6 +522,35 @@ void uiStyleInit(void)
BLF_size(blf_mono_font, 12 * U.pixelsize, 72);
+ /* Set default flags based on UI preferences (not render fonts) */
+ {
+ int flag_enable = 0, flag_disable = 0;
+ if ((U.text_render & USER_TEXT_DISABLE_HINTING) == 0) {
+ flag_enable |= BLF_HINTING;
+ }
+ else {
+ flag_disable |= BLF_HINTING;
+ }
+
+ if (U.text_render & USER_TEXT_DISABLE_AA) {
+ flag_enable |= BLF_MONOCHROME;
+ }
+ else {
+ flag_disable |= BLF_MONOCHROME;
+ }
+
+ for (font = U.uifonts.first; font; font = font->next) {
+ if (font->blf_id != -1) {
+ BLF_enable(font->blf_id, flag_enable);
+ BLF_disable(font->blf_id, flag_disable);
+ }
+ }
+ if (blf_mono_font != -1) {
+ BLF_enable(blf_mono_font, flag_enable);
+ BLF_disable(blf_mono_font, flag_disable);
+ }
+ }
+
/**
* Second for rendering else we get threading problems,
*
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 6110d5f3466..e81ad1428d1 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -39,6 +39,8 @@
#include "DNA_object_force_types.h"
#include "DNA_brush_types.h"
#include "DNA_texture_types.h"
+#include "DNA_gpencil_modifier_types.h"
+#include "DNA_shader_fx_types.h"
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
@@ -57,6 +59,7 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_gpencil_modifier.h"
#include "BKE_idcode.h"
#include "BKE_idprop.h"
#include "BKE_layer.h"
@@ -71,6 +74,7 @@
#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_screen.h"
+#include "BKE_shader_fx.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
@@ -110,7 +114,7 @@ static void template_add_button_search_menu(
const bContext *C, uiLayout *layout, uiBlock *block,
PointerRNA *ptr, PropertyRNA *prop,
uiBlockCreateFunc block_func, void *block_argN, const char * const tip,
- const bool use_previews, const bool editable)
+ const bool use_previews, const bool editable, const bool live_icon)
{
PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop);
ID *id = (active_ptr.data && RNA_struct_is_ID(active_ptr.type)) ? active_ptr.data : NULL;
@@ -146,7 +150,14 @@ static void template_add_button_search_menu(
}
else {
but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, tip);
- ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
+
+ if (live_icon) {
+ int icon = id ? ui_id_icon_get(C, id, false) : RNA_struct_ui_icon(type);
+ ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ }
+ else {
+ ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
+ }
if (id) {
/* default dragging of icon for id browse buttons */
UI_but_drag_set_id(but, id);
@@ -162,7 +173,8 @@ static uiBlock *template_common_search_menu(
const bContext *C, ARegion *region,
uiButSearchFunc search_func, void *search_arg,
uiButHandleFunc handle_func, void *active_item,
- const int preview_rows, const int preview_cols)
+ const int preview_rows, const int preview_cols,
+ float scale)
{
static char search[256];
wmWindow *win = CTX_wm_window(C);
@@ -177,8 +189,8 @@ static uiBlock *template_common_search_menu(
/* preview thumbnails */
if (preview_rows > 0 && preview_cols > 0) {
- const int w = 4 * U.widget_unit * preview_cols;
- const int h = 5 * U.widget_unit * preview_rows;
+ const int w = 4 * U.widget_unit * preview_cols * scale;
+ const int h = 5 * U.widget_unit * preview_rows * scale;
/* fake button, it holds space for search items */
uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
@@ -237,6 +249,7 @@ typedef struct TemplateID {
short filter;
int prv_rows, prv_cols;
bool preview;
+ float scale;
} TemplateID;
/* Search browse menu, assign */
@@ -382,7 +395,7 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
return template_common_search_menu(
C, ar, id_search_cb_p, &template_ui, template_ID_set_property_cb, active_item_ptr.data,
- template_ui.prv_rows, template_ui.prv_cols);
+ template_ui.prv_rows, template_ui.prv_cols, template_ui.scale);
}
/************************ ID Template ***************************/
@@ -630,7 +643,8 @@ static uiBut *template_id_def_new_but(
static void template_ID(
bContext *C, uiLayout *layout, TemplateID *template_ui, StructRNA *type, int flag,
- const char *newop, const char *openop, const char *unlinkop)
+ const char *newop, const char *openop, const char *unlinkop,
+ const bool live_icon)
{
uiBut *but;
uiBlock *block;
@@ -655,7 +669,7 @@ static void template_ID(
template_add_button_search_menu(
C, layout, block, &template_ui->ptr, template_ui->prop,
id_search_menu, MEM_dupallocN(template_ui), TIP_(template_id_browse_tip(type)),
- use_previews, editable);
+ use_previews, editable, live_icon);
}
/* text button with name */
@@ -860,7 +874,8 @@ static void ui_template_id(
uiLayout *layout, bContext *C,
PointerRNA *ptr, const char *propname,
const char *newop, const char *openop, const char *unlinkop,
- int flag, int prv_rows, int prv_cols, int filter, bool use_tabs)
+ int flag, int prv_rows, int prv_cols, int filter, bool use_tabs,
+ float scale, bool live_icon)
{
TemplateID *template_ui;
PropertyRNA *prop;
@@ -879,6 +894,7 @@ static void ui_template_id(
template_ui->prop = prop;
template_ui->prv_rows = prv_rows;
template_ui->prv_cols = prv_cols;
+ template_ui->scale = scale;
if ((flag & UI_ID_PIN) == 0) {
template_ui->filter = filter;
@@ -907,7 +923,7 @@ static void ui_template_id(
}
else {
uiLayoutRow(layout, true);
- template_ID(C, layout, template_ui, type, flag, newop, openop, unlinkop);
+ template_ID(C, layout, template_ui, type, flag, newop, openop, unlinkop, live_icon);
}
}
@@ -916,13 +932,14 @@ static void ui_template_id(
void uiTemplateID(
uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
- const char *openop, const char *unlinkop, int filter)
+ const char *openop, const char *unlinkop,
+ int filter, const bool live_icon)
{
ui_template_id(
layout, C, ptr, propname,
newop, openop, unlinkop,
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE,
- 0, 0, filter, false);
+ 0, 0, filter, false, 1.0f, live_icon);
}
void uiTemplateIDBrowse(
@@ -933,7 +950,7 @@ void uiTemplateIDBrowse(
layout, C, ptr, propname,
newop, openop, unlinkop,
UI_ID_BROWSE | UI_ID_RENAME,
- 0, 0, filter, false);
+ 0, 0, filter, false, 1.0f, false);
}
void uiTemplateIDPreview(
@@ -944,7 +961,18 @@ void uiTemplateIDPreview(
layout, C, ptr, propname,
newop, openop, unlinkop,
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS,
- rows, cols, filter, false);
+ rows, cols, filter, false, 1.0f, false);
+}
+
+void uiTemplateGpencilColorPreview(
+ uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname,
+ int rows, int cols, float scale, int filter)
+{
+ ui_template_id(
+ layout, C, ptr, propname,
+ NULL, NULL, NULL,
+ UI_ID_BROWSE | UI_ID_PREVIEWS | UI_ID_DELETE,
+ rows, cols, filter, false, scale < 0.5f ? 0.5f : scale, false);
}
/**
@@ -960,7 +988,7 @@ void uiTemplateIDTabs(
layout, C, ptr, propname,
newop, openop, unlinkop,
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE,
- 0, 0, filter, true);
+ 0, 0, filter, true, 1.0f, false);
}
/************************ ID Chooser Template ***************************/
@@ -1057,12 +1085,12 @@ static uiBlock *template_search_menu(bContext *C, ARegion *region, void *arg_tem
return template_common_search_menu(
C, region, ui_rna_collection_search_cb, &template_search,
template_search_handle_cb, active_ptr.data,
- template_search.preview_rows, template_search.preview_cols);
+ template_search.preview_rows, template_search.preview_cols, 1.0f);
}
static void template_search_add_button_searchmenu(
const bContext *C, uiLayout *layout, uiBlock *block,
- TemplateSearch *template_search, const bool editable)
+ TemplateSearch *template_search, const bool editable, const bool live_icon)
{
const char *ui_description = RNA_property_ui_description(template_search->search_data.target_prop);
@@ -1070,7 +1098,7 @@ static void template_search_add_button_searchmenu(
C, layout, block,
&template_search->search_data.target_ptr, template_search->search_data.target_prop,
template_search_menu, MEM_dupallocN(template_search), ui_description,
- template_search->use_previews, editable);
+ template_search->use_previews, editable, live_icon);
}
static void template_search_add_button_name(
@@ -1116,7 +1144,7 @@ static void template_search_buttons(
uiLayoutRow(layout, true);
UI_block_align_begin(block);
- template_search_add_button_searchmenu(C, layout, block, template_search, editable);
+ template_search_add_button_searchmenu(C, layout, block, template_search, editable, false);
template_search_add_button_name(block, &active_ptr, type);
template_search_add_button_operator(block, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, editable);
template_search_add_button_operator(block, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, editable);
@@ -1539,14 +1567,250 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr)
return NULL;
}
+/************************ Grease Pencil Modifier Template *************************/
-/************************ Redo Buttons Template *************************/
+static uiLayout *gpencil_draw_modifier(
+ uiLayout *layout, Object *ob,
+ GpencilModifierData *md)
+{
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(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);
+
+ /* modifier name */
+ if (mti->isDisabled && mti->isDisabled(md, 0)) {
+ uiLayoutSetRedAlert(row, true);
+ }
+ 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);
-static bool template_operator_redo_property_buts_poll(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
+ if (mti->flags & eGpencilModifierTypeFlag_SupportsEditmode) {
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetActive(sub, false);
+ uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE);
+ }
+
+ 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);
+
+ /* modifier settings (under the header) --------------------------------------------------- */
+ if (md->mode & eGpencilModifierMode_Expanded) {
+ /* apply/convert/copy */
+ box = uiLayoutBox(column);
+ row = uiLayoutRow(box, false);
+
+ /* only here obdata, the rest of modifiers is ob level */
+ UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+
+ uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
+ uiItemEnumO(row, "OBJECT_OT_gpencil_modifier_apply", CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),
+ 0, "apply_as", MODIFIER_APPLY_DATA);
+
+ uiItemO(row, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy"), ICON_NONE,
+ "OBJECT_OT_gpencil_modifier_copy");
+
+ /* 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);
+ }
+
+ /* error messages */
+ if (md->error) {
+ box = uiLayoutBox(column);
+ row = uiLayoutRow(box, false);
+ uiItemL(row, md->error, ICON_ERROR);
+ }
+
+ return result;
+}
+
+uiLayout *uiTemplateGpencilModifier(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- return (RNA_property_tags(prop) & OP_PROP_TAG_ADVANCED) == 0;
+ 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;
+ }
+
+ ob = ptr->id.data;
+ md = ptr->data;
+
+ if (!ob || !(GS(ob->id.name) == ID_OB)) {
+ RNA_warning("Expected modifier on object");
+ return NULL;
+ }
+
+ UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
+
+ /* 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);
+ }
+
+ return NULL;
}
+/************************ Shader FX Template *************************/
+
+static uiLayout *gpencil_draw_shaderfx(uiLayout *layout, Object *ob,
+ ShaderFxData *md)
+{
+ const ShaderFxTypeInfo *mti = BKE_shaderfxType_getInfo(md->type);
+ PointerRNA ptr;
+ uiBlock *block;
+ uiLayout *box, *column, *row, *sub;
+ uiLayout *result = NULL;
+
+ /* create RNA pointer */
+ RNA_pointer_create(&ob->id, &RNA_ShaderFx, md, &ptr);
+
+ column = uiLayoutColumn(layout, true);
+ uiLayoutSetContextPointer(column, "shaderfx", &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);
+
+ /* shader-type icon */
+ uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* effect name */
+ if (mti->isDisabled && mti->isDisabled(md, 0)) {
+ uiLayoutSetRedAlert(row, true);
+ }
+ 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 & eShaderFxTypeFlag_SupportsEditmode) {
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetActive(sub, false);
+ uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE);
+ }
+
+ UI_block_align_end(block);
+
+ /* 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);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ uiItemO(row, "", ICON_X, "OBJECT_OT_shaderfx_remove");
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* 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);
+ }
+
+ /* error messages */
+ if (md->error) {
+ box = uiLayoutBox(column);
+ row = uiLayoutRow(box, false);
+ uiItemL(row, md->error, ICON_ERROR);
+ }
+
+ return result;
+}
+
+uiLayout *uiTemplateShaderFx(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ 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;
+ }
+
+ ob = ptr->id.data;
+ fx = ptr->data;
+
+ if (!ob || !(GS(ob->id.name) == ID_OB)) {
+ RNA_warning("Expected shader fx on object");
+ return NULL;
+ }
+
+ 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);
+ }
+
+ return NULL;
+}
+
+/************************ Redo Buttons Template *************************/
+
static void template_operator_redo_property_buts_draw(
const bContext *C, wmOperator *op,
uiLayout *layout, int layout_flags,
@@ -1560,8 +1824,9 @@ static void template_operator_redo_property_buts_draw(
else {
/* Might want to make label_align adjustable somehow. */
eAutoPropButsReturn return_info = uiTemplateOperatorPropertyButs(
- C, layout, op, r_has_advanced ? template_operator_redo_property_buts_poll : NULL,
- UI_BUT_LABEL_ALIGN_NONE, layout_flags);
+ C, layout, op,
+ UI_BUT_LABEL_ALIGN_NONE,
+ layout_flags);
if (return_info & UI_PROP_BUTS_ANY_FAILED_CHECK) {
if (r_has_advanced) {
*r_has_advanced = true;
@@ -3043,6 +3308,24 @@ void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname,
}
}
+void uiTemplateCryptoPicker(uiLayout *layout, PointerRNA *ptr, const char *propname)
+{
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ uiBlock *block;
+ uiBut *but;
+
+ if (!prop) {
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ block = uiLayoutGetBlock(layout);
+
+ but = uiDefIconTextButO(block, UI_BTYPE_BUT, "UI_OT_eyedropper_color_crypto", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, RNA_property_ui_name(prop), 0, 0, UI_UNIT_X, UI_UNIT_Y, RNA_property_ui_description(prop));
+ but->rnapoin = *ptr;
+ but->rnaprop = prop;
+ but->rnaindex = -1;
+}
/********************* Layer Buttons Template ************************/
@@ -3930,13 +4213,30 @@ static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt,
}
#endif
+struct uiTemplateOperatorPropertyPollParam {
+ const bContext *C;
+ wmOperator *op;
+ short flag;
+};
+
+static bool ui_layout_operator_buts_poll_property(
+ struct PointerRNA *UNUSED(ptr), struct PropertyRNA *prop, void *user_data)
+{
+ struct uiTemplateOperatorPropertyPollParam *params = user_data;
+ if ((params->flag & UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED) &&
+ (RNA_property_tags(prop) & OP_PROP_TAG_ADVANCED))
+ {
+ return false;
+ }
+ return params->op->type->poll_property(params->C, params->op, prop);
+}
+
/**
* Draw Operator property buttons for redoing execution with different settings.
* This function does not initialize the layout, functions can be called on the layout before and after.
*/
eAutoPropButsReturn uiTemplateOperatorPropertyButs(
const bContext *C, uiLayout *layout, wmOperator *op,
- bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
const eButLabelAlign label_align, const short flag)
{
uiBlock *block = uiLayoutGetBlock(layout);
@@ -3995,13 +4295,18 @@ eAutoPropButsReturn uiTemplateOperatorPropertyButs(
else {
wmWindowManager *wm = CTX_wm_manager(C);
PointerRNA ptr;
+ struct uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op, .flag = flag};
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
uiLayoutSetPropSep(layout, true);
/* main draw call */
- return_info = uiDefAutoButsRNA(layout, &ptr, check_prop, label_align, (flag & UI_TEMPLATE_OP_PROPS_COMPACT));
+ return_info = uiDefAutoButsRNA(
+ layout, &ptr,
+ op->type->poll_property ? ui_layout_operator_buts_poll_property : NULL,
+ op->type->poll_property ? &user_data : NULL,
+ label_align, (flag & UI_TEMPLATE_OP_PROPS_COMPACT));
if ((return_info & UI_PROP_BUTS_NONE_ADDED) && (flag & UI_TEMPLATE_OP_PROPS_SHOW_EMPTY)) {
uiItemL(layout, IFACE_("No Properties"), ICON_NONE);
@@ -4588,7 +4893,7 @@ void uiTemplateCacheFile(uiLayout *layout, bContext *C, PointerRNA *ptr, const c
uiLayoutSetContextPointer(layout, "edit_cachefile", &fileptr);
- uiTemplateID(layout, C, ptr, propname, NULL, "CACHEFILE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, propname, NULL, "CACHEFILE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
if (!file) {
return;
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index d080397c488..60aa79e1093 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -159,7 +159,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
*/
eAutoPropButsReturn uiDefAutoButsRNA(
uiLayout *layout, PointerRNA *ptr,
- bool (*check_prop)(PointerRNA *, PropertyRNA *),
+ bool (*check_prop)(PointerRNA *ptr, PropertyRNA *prop, void *user_data), void *user_data,
const eButLabelAlign label_align, const bool compact)
{
eAutoPropButsReturn return_info = UI_PROP_BUTS_NONE_ADDED;
@@ -174,7 +174,7 @@ eAutoPropButsReturn uiDefAutoButsRNA(
if (flag & PROP_HIDDEN) {
continue;
}
- if (check_prop && check_prop(ptr, prop) == 0) {
+ if (check_prop && check_prop(ptr, prop, user_data) == 0) {
return_info |= UI_PROP_BUTS_ANY_FAILED_CHECK;
continue;
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index fea88388be7..019aabdb466 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -247,22 +247,22 @@ static const int tria_vcount[ROUNDBOX_TRIA_MAX] = {
};
static struct {
- Gwn_Batch *roundbox_widget[ROUNDBOX_TRIA_MAX];
+ GPUBatch *roundbox_widget[ROUNDBOX_TRIA_MAX];
- Gwn_Batch *roundbox_simple;
- Gwn_Batch *roundbox_simple_aa;
- Gwn_Batch *roundbox_simple_outline;
- Gwn_Batch *roundbox_shadow;
+ GPUBatch *roundbox_simple;
+ GPUBatch *roundbox_simple_aa;
+ GPUBatch *roundbox_simple_outline;
+ GPUBatch *roundbox_shadow;
- Gwn_VertFormat format;
+ GPUVertFormat format;
uint vflag_id;
} g_ui_batch_cache = {{0}};
-static Gwn_VertFormat *vflag_format(void)
+static GPUVertFormat *vflag_format(void)
{
if (g_ui_batch_cache.format.attr_len == 0) {
- Gwn_VertFormat *format = &g_ui_batch_cache.format;
- g_ui_batch_cache.vflag_id = GWN_vertformat_attr_add(format, "vflag", GWN_COMP_U32, 1, GWN_FETCH_INT);
+ GPUVertFormat *format = &g_ui_batch_cache.format;
+ g_ui_batch_cache.vflag_id = GPU_vertformat_attr_add(format, "vflag", GPU_COMP_U32, 1, GPU_FETCH_INT);
}
return &g_ui_batch_cache.format;
}
@@ -273,17 +273,17 @@ static Gwn_VertFormat *vflag_format(void)
#define NO_AA WIDGET_AA_JITTER
static void set_roundbox_vertex_data(
- Gwn_VertBufRaw *vflag_step, uint32_t d)
+ GPUVertBufRaw *vflag_step, uint32_t d)
{
- uint32_t *data = GWN_vertbuf_raw_step(vflag_step);
+ uint32_t *data = GPU_vertbuf_raw_step(vflag_step);
*data = d;
}
static uint32_t set_roundbox_vertex(
- Gwn_VertBufRaw *vflag_step,
+ GPUVertBufRaw *vflag_step,
int corner_id, int corner_v, int jit_v, bool inner, bool emboss, int color)
{
- uint32_t *data = GWN_vertbuf_raw_step(vflag_step);
+ uint32_t *data = GPU_vertbuf_raw_step(vflag_step);
*data = corner_id;
*data |= corner_v << 2;
*data |= jit_v << 6;
@@ -294,10 +294,10 @@ static uint32_t set_roundbox_vertex(
}
static uint32_t set_tria_vertex(
- Gwn_VertBufRaw *vflag_step,
+ GPUVertBufRaw *vflag_step,
int tria_type, int tria_v, int tria_id, int jit_v)
{
- uint32_t *data = GWN_vertbuf_raw_step(vflag_step);
+ 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];
}
@@ -308,7 +308,7 @@ static uint32_t set_tria_vertex(
return *data;
}
-static void roundbox_batch_add_tria(Gwn_VertBufRaw *vflag_step, int tria, uint32_t last_data)
+static void roundbox_batch_add_tria(GPUVertBufRaw *vflag_step, int tria, uint32_t last_data)
{
const int tria_num = ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW, ROUNDBOX_TRIA_MENU) ? 1 : 2;
/* for each tria */
@@ -324,12 +324,12 @@ static void roundbox_batch_add_tria(Gwn_VertBufRaw *vflag_step, int tria, uint32
}
}
-Gwn_Batch *ui_batch_roundbox_widget_get(int tria)
+GPUBatch *ui_batch_roundbox_widget_get(int tria)
{
if (g_ui_batch_cache.roundbox_widget[tria] == NULL) {
uint32_t last_data;
- Gwn_VertBufRaw vflag_step;
- Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(vflag_format());
+ GPUVertBufRaw vflag_step;
+ 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) */
@@ -341,8 +341,8 @@ Gwn_Batch *ui_batch_roundbox_widget_get(int tria)
vcount += (tria_vcount[tria] + 2) * WIDGET_AA_JITTER; /* tria2 */
}
}
- GWN_vertbuf_data_alloc(vbo, vcount);
- GWN_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
+ 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--) {
@@ -383,15 +383,15 @@ Gwn_Batch *ui_batch_roundbox_widget_get(int tria)
if (tria) {
roundbox_batch_add_tria(&vflag_step, tria, last_data);
}
- g_ui_batch_cache.roundbox_widget[tria] = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ 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];
}
-Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased)
+GPUBatch *ui_batch_roundbox_get(bool filled, bool antialiased)
{
- Gwn_Batch **batch = NULL;
+ GPUBatch **batch = NULL;
if (filled) {
if (antialiased)
@@ -408,13 +408,13 @@ Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased)
if (*batch == NULL) {
uint32_t last_data;
- Gwn_VertBufRaw vflag_step;
- Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(vflag_format());
+ 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;
- GWN_vertbuf_data_alloc(vbo, vcount);
- GWN_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
+ GPU_vertbuf_data_alloc(vbo, vcount);
+ GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
if (filled) {
for (int j = 0; j < WIDGET_AA_JITTER; j++) {
@@ -435,7 +435,7 @@ Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased)
break;
}
}
- *batch = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ *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++) {
@@ -451,7 +451,7 @@ Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased)
break;
}
}
- *batch = GWN_batch_create_ex(GWN_PRIM_LINE_LOOP, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ *batch = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
gpu_batch_presets_register(*batch);
@@ -459,15 +459,15 @@ Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased)
return *batch;
}
-Gwn_Batch *ui_batch_roundbox_shadow_get(void)
+GPUBatch *ui_batch_roundbox_shadow_get(void)
{
if (g_ui_batch_cache.roundbox_shadow == NULL) {
uint32_t last_data;
- Gwn_VertBufRaw vflag_step;
- Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(vflag_format());
+ GPUVertBufRaw vflag_step;
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format());
int vcount = (WIDGET_SIZE_MAX + 1) * 2 + 2 + WIDGET_SIZE_MAX;
- GWN_vertbuf_data_alloc(vbo, vcount);
- GWN_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
+ GPU_vertbuf_data_alloc(vbo, vcount);
+ GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
for (int c = 0; c < 4; c++) {
for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
@@ -488,7 +488,7 @@ Gwn_Batch *ui_batch_roundbox_shadow_get(void)
set_roundbox_vertex(&vflag_step, c2, a2, NO_AA, true, false, INNER);
}
}
- g_ui_batch_cache.roundbox_shadow = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ g_ui_batch_cache.roundbox_shadow = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
gpu_batch_presets_register(g_ui_batch_cache.roundbox_shadow);
}
return g_ui_batch_cache.roundbox_shadow;
@@ -513,11 +513,11 @@ void UI_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y
GPU_blend(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(draw_color);
- immBegin(GWN_PRIM_TRIS, 3 * WIDGET_AA_JITTER);
+ immBegin(GPU_PRIM_TRIS, 3 * WIDGET_AA_JITTER);
/* for each AA step */
for (int j = 0; j < WIDGET_AA_JITTER; j++) {
@@ -556,14 +556,14 @@ void UI_draw_anti_fan(float tri_array[][2], unsigned int length, const float col
GPU_blend(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(draw_color);
/* for each AA step */
for (int j = 0; j < WIDGET_AA_JITTER; j++) {
- immBegin(GWN_PRIM_TRI_FAN, length);
+ immBegin(GPU_PRIM_TRI_FAN, length);
immVertex2f(pos, tri_array[0][0], tri_array[0][1]);
immVertex2f(pos, tri_array[1][0], tri_array[1][1]);
@@ -1083,8 +1083,8 @@ static void widgetbase_set_uniform_colors_ubv(
#define MAX_WIDGET_BASE_BATCH 6
#define MAX_WIDGET_PARAMETERS 11
-struct {
- Gwn_Batch *batch; /* Batch type */
+static struct {
+ GPUBatch *batch; /* Batch type */
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH];
int count;
bool enabled;
@@ -1097,22 +1097,22 @@ void UI_widgetbase_draw_cache_flush(void)
if (g_widget_base_batch.count == 0)
return;
- Gwn_Batch *batch = g_widget_base_batch.batch;
+ GPUBatch *batch = g_widget_base_batch.batch;
if (g_widget_base_batch.count == 1) {
/* draw single */
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GWN_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)g_widget_base_batch.params);
- GWN_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
- GWN_batch_draw(batch);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
+ GPU_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)g_widget_base_batch.params);
+ GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
+ GPU_batch_draw(batch);
}
else {
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE_INST);
- GWN_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH,
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE_INST);
+ GPU_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH,
(float *)g_widget_base_batch.params);
- GWN_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
- gpuBindMatrices(batch->interface);
- GWN_batch_draw_range_ex(batch, 0, g_widget_base_batch.count, true);
- GWN_batch_program_use_end(batch);
+ GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
+ GPU_matrix_bind(batch->interface);
+ GPU_batch_draw_range_ex(batch, 0, g_widget_base_batch.count, true);
+ GPU_batch_program_use_end(batch);
}
g_widget_base_batch.count = 0;
}
@@ -1135,7 +1135,7 @@ void UI_widgetbase_draw_cache_end(void)
GPU_blend(false);
}
-static void draw_widgetbase_batch(Gwn_Batch *batch, uiWidgetBase *wtb)
+static void draw_widgetbase_batch(GPUBatch *batch, uiWidgetBase *wtb)
{
wtb->uniform_params.tria1_size = wtb->tria1.size;
wtb->uniform_params.tria2_size = wtb->tria2.size;
@@ -1171,10 +1171,10 @@ static void draw_widgetbase_batch(Gwn_Batch *batch, uiWidgetBase *wtb)
else {
float checker_params[3] = {UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 8.0f};
/* draw single */
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&wtb->uniform_params);
- GWN_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
- GWN_batch_draw(batch);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&wtb->uniform_params);
+ GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
+ GPU_batch_draw(batch);
}
}
@@ -1228,7 +1228,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, const uiWidgetColors *wcol)
if (inner_col1[3] || inner_col2[3] || outline_col[3] || emboss_col[3] || tria_col[3] || alpha_check) {
widgetbase_set_uniform_colors_ubv(wtb, inner_col1, inner_col2, outline_col, emboss_col, tria_col, alpha_check);
- Gwn_Batch *roundbox_batch = ui_batch_roundbox_widget_get(wtb->tria1.type);
+ GPUBatch *roundbox_batch = ui_batch_roundbox_widget_get(wtb->tria1.type);
draw_widgetbase_batch(roundbox_batch, wtb);
}
@@ -1494,7 +1494,7 @@ float UI_text_clip_middle_ex(
rpart = rpart_buf;
}
- l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, parts_strwidth, &rpart_width);
+ l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, parts_strwidth, NULL);
if (l_end < 10 || min_ff(parts_strwidth, strwidth - okwidth) < minwidth) {
/* If we really have no place, or we would clip a very small piece of string in the middle,
* only show start of string.
@@ -1504,7 +1504,7 @@ float UI_text_clip_middle_ex(
else {
size_t r_offset, r_len;
- r_offset = BLF_width_to_rstrlen(fstyle->uifont_id, str, max_len, parts_strwidth, &rpart_width);
+ r_offset = BLF_width_to_rstrlen(fstyle->uifont_id, str, max_len, parts_strwidth, NULL);
r_len = strlen(str + r_offset) + 1; /* +1 for the trailing '\0'. */
if (l_end + sep_len + r_len + rpart_len > max_len) {
@@ -1525,6 +1525,7 @@ float UI_text_clip_middle_ex(
if (rpart) {
/* Add back preserved right part to our shorten str. */
memcpy(str + final_lpart_len, rpart, rpart_len + 1); /* +1 for trailing '\0'. */
+ okwidth += rpart_width;
}
strwidth = BLF_width(fstyle->uifont_id, str, max_len);
@@ -1836,7 +1837,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
selwidth_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selend - but->ofs);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ubv((unsigned char *)wcol->item);
@@ -1872,7 +1873,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
UI_widgetbase_draw_cache_flush();
GPU_blend(false);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3f(0.2f, 0.6f, 0.9f);
@@ -2423,7 +2424,7 @@ static void widget_softshadow(const rcti *rect, int roundboxalign, const float r
/* we draw a number of increasing size alpha quad strips */
alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -2475,7 +2476,7 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir
static void ui_hsv_cursor(float x, float y)
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -2571,13 +2572,13 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
ui_color_picker_to_rgb(0.0f, 0.0f, hsv[2], colcent, colcent + 1, colcent + 2);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- immBegin(GWN_PRIM_TRI_FAN, tot + 2);
+ immBegin(GPU_PRIM_TRI_FAN, tot + 2);
immAttrib3fv(color, colcent);
immVertex2f(pos, centx, centy);
@@ -2598,7 +2599,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
/* fully rounded outline */
format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -2682,12 +2683,12 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons
}
/* old below */
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- immBegin(GWN_PRIM_TRIS, steps * 3 * 6);
+ immBegin(GPU_PRIM_TRIS, steps * 3 * 6);
for (dx = 0.0f; dx < 0.999f; dx += color_step) { /* 0.999 = prevent float inaccuracy for steps */
const float dx_next = dx + color_step;
@@ -2843,7 +2844,7 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
ui_hsv_cursor(x, y);
/* outline */
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3ub(0, 0, 0);
imm_draw_box_wire_2d(pos, (rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax));
@@ -2940,14 +2941,14 @@ static void ui_draw_separator(const rcti *rect, uiWidgetColors *wcol)
30
};
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
GPU_blend(true);
immUniformColor4ubv(col);
GPU_line_width(1.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, rect->xmin, y);
immVertex2f(pos, rect->xmax, y);
immEnd();
@@ -3402,11 +3403,11 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
UI_widgetbase_draw_cache_flush();
GPU_blend(false);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3f(bw, bw, bw);
- immBegin(GWN_PRIM_TRIS, 3);
+ immBegin(GPU_PRIM_TRIS, 3);
immVertex2f(pos, rect->xmin + 0.1f * width, rect->ymin + 0.9f * height);
immVertex2f(pos, rect->xmin + 0.1f * width, rect->ymin + 0.5f * height);
immVertex2f(pos, rect->xmin + 0.5f * width, rect->ymin + 0.9f * height);
@@ -3783,7 +3784,7 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
/* note: drawextra can change rect +1 or -1, to match round errors of existing previews */
but->block->drawextra(C, but->poin, but->block->drawextra_arg1, but->block->drawextra_arg2, rect);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* make mask to draw over image */
@@ -4420,11 +4421,11 @@ static void ui_draw_popover_back_impl(
/* Draw popover arrow (top/bottom) */
if (ELEM(direction, UI_DIR_UP, UI_DIR_DOWN)) {
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ubv((unsigned char *)wcol->inner);
GPU_blend(true);
- immBegin(GWN_PRIM_TRIS, 3);
+ immBegin(GPU_PRIM_TRIS, 3);
if (direction == UI_DIR_DOWN) {
const float y = rect->ymax;
immVertex2f(pos, cent_x - unit_half, y);
@@ -4476,10 +4477,10 @@ static void draw_disk_shaded(
unsigned char r_col[4];
unsigned int pos, col;
- Gwn_VertFormat *format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (shaded) {
- col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
}
else {
@@ -4487,7 +4488,7 @@ static void draw_disk_shaded(
immUniformColor4ubv((unsigned char *)col1);
}
- immBegin(GWN_PRIM_TRI_STRIP, subd * 2);
+ immBegin(GPU_PRIM_TRI_STRIP, subd * 2);
for (i = 0; i < subd; i++) {
float a;
@@ -4532,8 +4533,8 @@ void ui_draw_pie_center(uiBlock *block)
float angle = atan2f(pie_dir[1], pie_dir[0]);
float range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? M_PI_2 : M_PI_4;
- gpuPushMatrix();
- gpuTranslate2f(cx, cy);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(cx, cy);
GPU_blend(true);
if (btheme->tui.wcol_pie_menu.shaded) {
@@ -4556,8 +4557,8 @@ void ui_draw_pie_center(uiBlock *block)
}
}
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ubv((unsigned char *)btheme->tui.wcol_pie_menu.outline);
@@ -4579,7 +4580,7 @@ void ui_draw_pie_center(uiBlock *block)
}
GPU_blend(false);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 47d664eaeb2..72023ebf2ae 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -83,7 +83,7 @@ static struct bThemeState g_theme_state = {
void ui_resources_init(void)
{
- UI_icons_init(BIFICONID_LAST);
+ UI_icons_init();
}
void ui_resources_free(void)
@@ -1536,15 +1536,6 @@ void init_userdef_do_versions(Main *bmain)
#undef USER_VERSION_ATLEAST
#define USER_VERSION_ATLEAST(ver, subver) MAIN_VERSION_ATLEAST((&(U)), ver, subver)
-
- if (!USER_VERSION_ATLEAST(269, 9)) {
- /* grease pencil - new layer color */
- if (U.gpencil_new_layer_col[3] < 0.1f) {
- /* defaults to black, but must at least be visible! */
- U.gpencil_new_layer_col[3] = 0.9f;
- }
- }
-
if (!USER_VERSION_ATLEAST(271, 5)) {
U.pie_menu_radius = 100;
U.pie_menu_threshold = 12;
@@ -1582,6 +1573,17 @@ void init_userdef_do_versions(Main *bmain)
for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
memcpy(btheme, &U_theme_default, sizeof(*btheme));
}
+
+ /* Annotations - new layer color
+ * Replace anything that used to be set if it looks like was left
+ * on the old default (i.e. black), which most users used
+ */
+ if ((U.gpencil_new_layer_col[3] < 0.1f) || (U.gpencil_new_layer_col[0] < 0.1f)) {
+ /* - New color matches the annotation pencil icon
+ * - Non-full alpha looks better!
+ */
+ ARRAY_SET_ITEMS(U.gpencil_new_layer_col, 0.38f, 0.61f, 0.78f, 0.9f);
+ }
}
/**
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 1b449877abe..3a527712367 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -1151,7 +1151,7 @@ void UI_view2d_view_restore(const bContext *C)
int height = BLI_rcti_size_y(&ar->winrct) + 1;
wmOrtho2(0.0f, (float)width, 0.0f, (float)height);
- gpuLoadIdentity();
+ GPU_matrix_identity_set();
// ED_region_pixelspace(CTX_wm_region(C));
}
@@ -1338,12 +1338,12 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
if (vertex_count == 0)
return;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GWN_PRIM_LINES, vertex_count);
+ immBegin(GPU_PRIM_LINES, vertex_count);
/* vertical lines */
if (flag & V2D_VERTICAL_LINES) {
@@ -1480,15 +1480,15 @@ void UI_view2d_constant_grid_draw(View2D *v2d, float step)
count_y = (v2d->cur.ymax - start_y) / step + 1;
if (count_x > 0 || count_y > 0) {
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
float theme_color[3];
UI_GetThemeColorShade3fv(TH_BACK, -10, theme_color);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GWN_PRIM_LINES, count_x * 2 + count_y * 2 + 4);
+ immBegin(GPU_PRIM_LINES, count_x * 2 + count_y * 2 + 4);
immAttrib3fv(color, theme_color);
for (int i = 0; i < count_x ; start_x += step, i++) {
@@ -1531,14 +1531,14 @@ void UI_view2d_multi_grid_draw(View2D *v2d, int colorid, float step, int level_s
vertex_count += 2 * ((int)((v2d->cur.xmax - v2d->cur.xmin) / lstep) + 1);
vertex_count += 2 * ((int)((v2d->cur.ymax - v2d->cur.ymin) / lstep) + 1);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
GPU_line_width(1.0f);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBeginAtMost(GWN_PRIM_LINES, vertex_count);
+ immBeginAtMost(GPU_PRIM_LINES, vertex_count);
for (int level = 0; level < totlevels; ++level) {
UI_GetThemeColorShade3ubv(colorid, offset, grid_line_color);
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index dfc401c1635..1c56dabb396 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -354,7 +354,7 @@ static int view_scrollright_exec(bContext *C, wmOperator *op)
}
/* set RNA-Props - only movement in positive x-direction */
- RNA_int_set(op->ptr, "deltax", 20);
+ RNA_int_set(op->ptr, "deltax", 40);
RNA_int_set(op->ptr, "deltay", 0);
/* apply movement, then we're done */
@@ -398,7 +398,7 @@ static int view_scrollleft_exec(bContext *C, wmOperator *op)
}
/* set RNA-Props - only movement in negative x-direction */
- RNA_int_set(op->ptr, "deltax", -20);
+ RNA_int_set(op->ptr, "deltax", -40);
RNA_int_set(op->ptr, "deltay", 0);
/* apply movement, then we're done */
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index 4717ef309f3..506dec2aa3e 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -124,8 +124,8 @@ static void draw_single_handle(const MaskLayer *mask_layer, const MaskSplinePoin
return;
}
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
const unsigned char rgb_gray[4] = {0x60, 0x60, 0x60, 0xff};
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -134,7 +134,7 @@ static void draw_single_handle(const MaskLayer *mask_layer, const MaskSplinePoin
/* this could be split into its own loop */
if (draw_type == MASK_DT_OUTLINE) {
GPU_line_width(3.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2fv(pos, point_pos);
immVertex2fv(pos, handle_pos);
immEnd();
@@ -154,7 +154,7 @@ static void draw_single_handle(const MaskLayer *mask_layer, const MaskSplinePoin
}
GPU_line_width(1.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2fv(pos, point_pos);
immVertex2fv(pos, handle_pos);
immEnd();
@@ -178,7 +178,7 @@ static void draw_single_handle(const MaskLayer *mask_layer, const MaskSplinePoin
immUniform4fv("outlineColor", point_color);
immUniformColor3fvAlpha(point_color, 0.25f);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex2fv(pos, handle_pos);
immEnd();
@@ -212,8 +212,8 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
immUniform1f("size", 0.7f * handle_size);
@@ -251,7 +251,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
immUniformThemeColor(TH_HANDLE_VERTEX);
}
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex2fv(pos, feather_point);
immEnd();
@@ -320,7 +320,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
else
immUniformThemeColor(TH_HANDLE_VERTEX);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex2fv(pos, vert);
immEnd();
@@ -350,7 +350,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 1.0f);
immUniform1f("size", 12.0f);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex2f(pos, x, y);
immEnd();
@@ -371,7 +371,7 @@ static void mask_color_active_tint(unsigned char r_rgb[4], const unsigned char r
}
}
-static void mask_draw_array(unsigned int pos, Gwn_PrimType prim_type, const float (*points)[2], unsigned int vertex_len)
+static void mask_draw_array(unsigned int pos, GPUPrimType prim_type, const float (*points)[2], unsigned int vertex_len)
{
immBegin(prim_type, vertex_len);
for (unsigned int i = 0; i < vertex_len; ++i) {
@@ -384,7 +384,7 @@ static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*
const bool is_feather, const bool is_active,
const unsigned char rgb_spline[4], const char draw_type)
{
- const Gwn_PrimType draw_method = (spline->flag & MASK_SPLINE_CYCLIC) ? GWN_PRIM_LINE_LOOP : GWN_PRIM_LINE_STRIP;
+ const GPUPrimType draw_method = (spline->flag & MASK_SPLINE_CYCLIC) ? GPU_PRIM_LINE_LOOP : GPU_PRIM_LINE_STRIP;
const unsigned char rgb_black[4] = {0x00, 0x00, 0x00, 0xff};
unsigned char rgb_tmp[4];
SpaceClip *sc = CTX_wm_space_clip(C);
@@ -402,8 +402,8 @@ static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*
}
}
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
switch (draw_type) {
@@ -695,17 +695,17 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
GPU_blend_set_func(GPU_DST_COLOR, GPU_ZERO);
}
- gpuPushMatrix();
- gpuTranslate2f(x, y);
- gpuScale2f(zoomx, zoomy);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(x, y);
+ GPU_matrix_scale_2f(zoomx, zoomy);
if (stabmat) {
- gpuMultMatrix(stabmat);
+ GPU_matrix_mul(stabmat);
}
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
immDrawPixelsTex(&state, 0.0f, 0.0f, width, height, GL_RED, GL_FLOAT, GL_NEAREST, buffer, 1.0f, 1.0f, NULL);
- gpuPopMatrix();
+ GPU_matrix_pop();
if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
GPU_blend(false);
@@ -715,13 +715,13 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
}
/* apply transformation so mask editing tools will assume drawing from the origin in normalized space */
- gpuPushMatrix();
- gpuTranslate2f(x + xofs, y + yofs);
- gpuScale2f(zoomx, zoomy);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(x + xofs, y + yofs);
+ GPU_matrix_scale_2f(zoomx, zoomy);
if (stabmat) {
- gpuMultMatrix(stabmat);
+ GPU_matrix_mul(stabmat);
}
- gpuScale2f(maxdim, maxdim);
+ GPU_matrix_scale_2f(maxdim, maxdim);
if (do_draw_cb) {
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
@@ -734,7 +734,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
}
- gpuPopMatrix();
+ GPU_matrix_pop();
}
void ED_mask_draw_frames(Mask *mask, ARegion *ar, const int cfra, const int sfra, const int efra)
@@ -747,12 +747,12 @@ void ED_mask_draw_frames(Mask *mask, ARegion *ar, const int cfra, const int sfra
unsigned int num_lines = BLI_listbase_count(&masklay->splines_shapes);
if (num_lines > 0) {
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ub(255, 175, 0, 255);
- immBegin(GWN_PRIM_LINES, 2 * num_lines);
+ immBegin(GPU_PRIM_LINES, 2 * num_lines);
for (MaskLayerShape *masklay_shape = masklay->splines_shapes.first;
masklay_shape;
diff --git a/source/blender/editors/mesh/editmesh_add_gizmo.c b/source/blender/editors/mesh/editmesh_add_gizmo.c
index be5c01e08df..6fa0eb33b89 100644
--- a/source/blender/editors/mesh/editmesh_add_gizmo.c
+++ b/source/blender/editors/mesh/editmesh_add_gizmo.c
@@ -160,14 +160,14 @@ static void gizmo_mesh_placement_update_from_op(GizmoPlacementGroup *man)
/* translate callbacks */
static void gizmo_placement_prop_matrix_get(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
void *value_p)
{
- GizmoPlacementGroup *man = mpr->parent_mgroup->customdata;
+ GizmoPlacementGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 16);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 16);
+ UNUSED_VARS_NDEBUG(gz_prop);
if (value_p != man->cage->matrix_offset) {
mul_m4_m4m4(value_p, man->cage->matrix_basis, man->cage->matrix_offset);
@@ -176,14 +176,14 @@ static void gizmo_placement_prop_matrix_get(
}
static void gizmo_placement_prop_matrix_set(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
const void *value)
{
- GizmoPlacementGroup *man = mpr->parent_mgroup->customdata;
+ GizmoPlacementGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
- BLI_assert(mpr_prop->type->array_length == 16);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 16);
+ UNUSED_VARS_NDEBUG(gz_prop);
float mat[4][4];
mul_m4_m4m4(mat, man->cage->matrix_basis, value);
@@ -197,38 +197,38 @@ static void gizmo_placement_prop_matrix_set(
gizmo_placement_exec(man);
}
-static bool gizmo_mesh_placement_poll(const bContext *C, wmGizmoGroupType *wgt)
+static bool gizmo_mesh_placement_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
wmOperator *op = WM_operator_last_redo(C);
if (op == NULL || !STREQ(op->type->idname, "MESH_OT_primitive_cube_add_gizmo")) {
- WM_gizmo_group_type_unlink_delayed_ptr(wgt);
+ WM_gizmo_group_type_unlink_delayed_ptr(gzgt);
return false;
}
return true;
}
static void gizmo_mesh_placement_modal_from_setup(
- const bContext *C, wmGizmoGroup *mgroup)
+ const bContext *C, wmGizmoGroup *gzgroup)
{
- GizmoPlacementGroup *man = mgroup->customdata;
+ GizmoPlacementGroup *man = gzgroup->customdata;
/* Initial size. */
{
- wmGizmo *mpr = man->cage;
- zero_m4(mpr->matrix_offset);
-
- /* TODO: support zero scaled matrix in 'GIZMO_WT_cage_3d'. */
- mpr->matrix_offset[0][0] = 0.01;
- mpr->matrix_offset[1][1] = 0.01;
- mpr->matrix_offset[2][2] = 0.01;
- mpr->matrix_offset[3][3] = 1.0f;
+ wmGizmo *gz = man->cage;
+ zero_m4(gz->matrix_offset);
+
+ /* TODO: support zero scaled matrix in 'GIZMO_GT_cage_3d'. */
+ gz->matrix_offset[0][0] = 0.01;
+ gz->matrix_offset[1][1] = 0.01;
+ gz->matrix_offset[2][2] = 0.01;
+ gz->matrix_offset[3][3] = 1.0f;
}
/* Start off dragging. */
{
wmWindow *win = CTX_wm_window(C);
ARegion *ar = CTX_wm_region(C);
- wmGizmo *mpr = man->cage;
+ wmGizmo *gz = man->cage;
{
float mat3[3][3];
@@ -239,19 +239,19 @@ static void gizmo_mesh_placement_modal_from_setup(
win->eventstate->y - ar->winrct.ymin,
},
location, mat3);
- copy_m4_m3(mpr->matrix_basis, mat3);
- copy_v3_v3(mpr->matrix_basis[3], location);
+ copy_m4_m3(gz->matrix_basis, mat3);
+ copy_v3_v3(gz->matrix_basis[3], location);
}
if (1) {
- wmGizmoMap *mmap = mgroup->parent_mmap;
+ wmGizmoMap *gzmap = gzgroup->parent_gzmap;
WM_gizmo_modal_set_from_setup(
- mmap, (bContext *)C, man->cage, ED_GIZMO_CAGE3D_PART_SCALE_MAX_X_MAX_Y_MAX_Z, win->eventstate);
+ gzmap, (bContext *)C, man->cage, ED_GIZMO_CAGE3D_PART_SCALE_MAX_X_MAX_Y_MAX_Z, win->eventstate);
}
}
}
-static void gizmo_mesh_placement_setup(const bContext *C, wmGizmoGroup *mgroup)
+static void gizmo_mesh_placement_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
wmOperator *op = WM_operator_last_redo(C);
@@ -260,11 +260,11 @@ static void gizmo_mesh_placement_setup(const bContext *C, wmGizmoGroup *mgroup)
}
struct GizmoPlacementGroup *man = MEM_callocN(sizeof(GizmoPlacementGroup), __func__);
- mgroup->customdata = man;
+ gzgroup->customdata = man;
- const wmGizmoType *wt_cage = WM_gizmotype_find("GIZMO_WT_cage_3d", true);
+ const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true);
- man->cage = WM_gizmo_new_ptr(wt_cage, mgroup, NULL);
+ man->cage = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL);
UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, man->cage->color);
@@ -293,32 +293,32 @@ static void gizmo_mesh_placement_setup(const bContext *C, wmGizmoGroup *mgroup)
});
}
- gizmo_mesh_placement_modal_from_setup(C, mgroup);
+ gizmo_mesh_placement_modal_from_setup(C, gzgroup);
}
static void gizmo_mesh_placement_draw_prepare(
- const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+ const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- GizmoPlacementGroup *man = mgroup->customdata;
+ GizmoPlacementGroup *man = gzgroup->customdata;
if (man->data.op->next) {
man->data.op = WM_operator_last_redo((bContext *)man->data.context);
}
gizmo_mesh_placement_update_from_op(man);
}
-static void MESH_WGT_add_bounds(struct wmGizmoGroupType *wgt)
+static void MESH_GGT_add_bounds(struct wmGizmoGroupType *gzgt)
{
- wgt->name = "Mesh Add Bounds";
- wgt->idname = "MESH_WGT_add_bounds";
+ gzgt->name = "Mesh Add Bounds";
+ gzgt->idname = "MESH_GGT_add_bounds";
- wgt->flag = WM_GIZMOGROUPTYPE_3D;
+ gzgt->flag = WM_GIZMOGROUPTYPE_3D;
- wgt->mmap_params.spaceid = SPACE_VIEW3D;
- wgt->mmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- wgt->poll = gizmo_mesh_placement_poll;
- wgt->setup = gizmo_mesh_placement_setup;
- wgt->draw_prepare = gizmo_mesh_placement_draw_prepare;
+ gzgt->poll = gizmo_mesh_placement_poll;
+ gzgt->setup = gizmo_mesh_placement_setup;
+ gzgt->draw_prepare = gizmo_mesh_placement_draw_prepare;
}
/** \} */
@@ -379,18 +379,18 @@ static int add_primitive_cube_gizmo_invoke(bContext *C, wmOperator *op, const wm
int ret = add_primitive_cube_gizmo_exec(C, op);
if (ret & OPERATOR_FINISHED) {
/* Setup gizmos */
- if (v3d && ((v3d->mpr_flag & V3D_GIZMO_HIDE) == 0)) {
+ if (v3d && ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0)) {
ARegion *ar = CTX_wm_region(C);
- wmGizmoMap *mmap = ar->gizmo_map;
- wmGizmoGroupType *wgt = WM_gizmogrouptype_find("MESH_WGT_add_bounds", false);
- wmGizmoGroup *mgroup = WM_gizmomap_group_find_ptr(mmap, wgt);
- if (mgroup != NULL) {
- GizmoPlacementGroup *man = mgroup->customdata;
+ wmGizmoMap *gzmap = ar->gizmo_map;
+ wmGizmoGroupType *gzgt = WM_gizmogrouptype_find("MESH_GGT_add_bounds", false);
+ wmGizmoGroup *gzgroup = WM_gizmomap_group_find_ptr(gzmap, gzgt);
+ if (gzgroup != NULL) {
+ GizmoPlacementGroup *man = gzgroup->customdata;
man->data.op = op;
- gizmo_mesh_placement_modal_from_setup(C, mgroup);
+ gizmo_mesh_placement_modal_from_setup(C, gzgroup);
}
else {
- WM_gizmo_group_type_ensure_ptr(wgt);
+ WM_gizmo_group_type_ensure_ptr(gzgt);
}
}
}
@@ -420,7 +420,7 @@ void MESH_OT_primitive_cube_add_gizmo(wmOperatorType *ot)
PropertyRNA *prop = RNA_def_float_matrix(ot->srna, "matrix", 4, 4, NULL, 0.0f, 0.0f, "Matrix", "", 0.0f, 0.0f);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- WM_gizmogrouptype_append(MESH_WGT_add_bounds);
+ WM_gizmogrouptype_append(MESH_GGT_add_bounds);
}
/** \} */
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index b73ce410626..e87abc6adf7 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -30,6 +30,7 @@
#include "BLI_string.h"
#include "BLI_math.h"
+#include "BLI_linklist_stack.h"
#include "BLT_translation.h"
@@ -38,6 +39,7 @@
#include "BKE_editmesh.h"
#include "BKE_unit.h"
#include "BKE_layer.h"
+#include "BKE_mesh.h"
#include "RNA_define.h"
#include "RNA_access.h"
@@ -95,7 +97,7 @@ typedef struct {
/* modal only */
float mcenter[2];
void *draw_handle_pixel;
- short mpr_flag;
+ short gizmo_flag;
short value_mode; /* Which value does mouse movement and numeric input affect? */
float segments; /* Segments as float so smooth mouse pan works in small increments */
} BevelData;
@@ -134,6 +136,98 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op)
}
}
+static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_strength)
+{
+ BKE_editmesh_lnorspace_update(em);
+ BM_normals_loops_edges_tag(em->bm, true);
+ const int cd_clnors_offset = CustomData_get_offset(&em->bm->ldata, CD_CUSTOMLOOPNORMAL);
+
+ BMesh *bm = em->bm;
+ BMFace *f;
+ BMLoop *l, *l_cur, *l_first;
+ BMIter fiter;
+
+ BMOpSlot *nslot = BMO_slot_get(bmop->slots_out, "normals.out"); /* Per vertex normals depending on hn_mode */
+
+ /* Similar functionality to bm_mesh_loops_calc_normals... Edges that can be smoothed are tagged */
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ l_cur = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if ((BM_elem_flag_test(l_cur->v, BM_ELEM_SELECT)) &&
+ ((!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG)) ||
+ (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_cur))))
+ {
+ /* Both adjacent loops are sharp, set clnor to face normal */
+ if (!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) && !BM_elem_flag_test(l_cur->prev->e, BM_ELEM_TAG)) {
+ const int loop_index = BM_elem_index_get(l_cur);
+ short *clnors = BM_ELEM_CD_GET_VOID_P(l_cur, cd_clnors_offset);
+ BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], f->no, clnors);
+ }
+ else {
+ /* Find next corresponding sharp edge in this smooth fan */
+ BMVert *v_pivot = l_cur->v;
+ float *calc_n = BLI_ghash_lookup(nslot->data.ghash, v_pivot);
+
+ BMEdge *e_next;
+ const BMEdge *e_org = l_cur->e;
+ BMLoop *lfan_pivot, *lfan_pivot_next;
+
+ lfan_pivot = l_cur;
+ e_next = lfan_pivot->e;
+ BLI_SMALLSTACK_DECLARE(loops, BMLoop *);
+ float cn_wght[3] = { 0.0f, 0.0f, 0.0f }, cn_unwght[3] = { 0.0f, 0.0f, 0.0f };
+
+ /* Fan through current vert and accumulate normals and loops */
+ while (true) {
+ lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next);
+ if (lfan_pivot_next) {
+ BLI_assert(lfan_pivot_next->v == v_pivot);
+ }
+ else {
+ e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e;
+ }
+
+ BLI_SMALLSTACK_PUSH(loops, lfan_pivot);
+ float cur[3];
+ mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f));
+ add_v3_v3(cn_wght, cur);
+
+ if (BM_elem_flag_test(lfan_pivot->f, BM_ELEM_SELECT))
+ add_v3_v3(cn_unwght, cur);
+
+ if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) {
+ break;
+ }
+ lfan_pivot = lfan_pivot_next;
+ }
+
+ normalize_v3(cn_wght);
+ normalize_v3(cn_unwght);
+ if (calc_n) {
+ mul_v3_fl(cn_wght, face_strength);
+ mul_v3_fl(calc_n, 1.0f - face_strength);
+ add_v3_v3(calc_n, cn_wght);
+ normalize_v3(calc_n);
+ }
+ while ((l = BLI_SMALLSTACK_POP(loops))) {
+ const int l_index = BM_elem_index_get(l);
+ short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset);
+ if (calc_n) {
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[l_index], calc_n, clnors);
+ }
+ else {
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[l_index], cn_unwght, clnors);
+ }
+ }
+ BLI_ghash_remove(nslot->data.ghash, v_pivot, NULL, MEM_freeN);
+ }
+ }
+ } while ((l_cur = l_cur->next) != l_first);
+ }
+}
+
static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
{
Scene *scene = CTX_data_scene(C);
@@ -201,8 +295,8 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
G.moving = G_TRANSFORM_EDIT;
if (v3d) {
- opdata->mpr_flag = v3d->mpr_flag;
- v3d->mpr_flag = V3D_GIZMO_HIDE;
+ opdata->gizmo_flag = v3d->gizmo_flag;
+ v3d->gizmo_flag = V3D_GIZMO_HIDE;
}
}
@@ -224,6 +318,10 @@ static bool edbm_bevel_calc(wmOperator *op)
const bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap");
int material = RNA_int_get(op->ptr, "material");
const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide");
+ const bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam");
+ const bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp");
+ const float hn_strength = RNA_float_get(op->ptr, "strength");
+ const int hnmode = RNA_enum_get(op->ptr, "hnmode");
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
@@ -238,11 +336,12 @@ static bool edbm_bevel_calc(wmOperator *op)
material = CLAMPIS(material, -1, em->ob->totcol - 1);
}
- 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",
- BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile,
- clamp_overlap, material, loop_slide);
+ 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 strength=%f hnmode=%i",
+ BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile,
+ clamp_overlap, material, loop_slide, mark_seam, mark_sharp, hn_strength, hnmode);
BMO_op_exec(em->bm, &bmop);
@@ -253,6 +352,10 @@ static bool edbm_bevel_calc(wmOperator *op)
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
}
+ if (hnmode != BEVEL_HN_NONE) {
+ bevel_harden_normals(em, &bmop, hn_strength);
+ }
+
/* no need to de-select existing geometry */
if (!EDBM_op_finish(em, &bmop, op, true)) {
continue;
@@ -284,7 +387,7 @@ static void edbm_bevel_exit(bContext *C, wmOperator *op)
}
ED_region_draw_cb_exit(ar->type, opdata->draw_handle_pixel);
if (v3d) {
- v3d->mpr_flag = opdata->mpr_flag;
+ v3d->gizmo_flag = opdata->gizmo_flag;
}
G.moving = 0;
}
@@ -603,6 +706,26 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
edbm_bevel_update_header(C, op);
handled = true;
break;
+ case UKEY:
+ if (event->val == KM_RELEASE)
+ break;
+ else {
+ bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam");
+ RNA_boolean_set(op->ptr, "mark_seam", !mark_seam);
+ edbm_bevel_calc(op);
+ handled = true;
+ break;
+ }
+ case KKEY:
+ if (event->val == KM_RELEASE)
+ break;
+ else {
+ bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp");
+ RNA_boolean_set(op->ptr, "mark_sharp", !mark_sharp);
+ edbm_bevel_calc(op);
+ handled = true;
+ break;
+ }
}
@@ -641,6 +764,13 @@ void MESH_OT_bevel(wmOperatorType *ot)
{0, NULL, 0, NULL, NULL},
};
+ static EnumPropertyItem harden_normals_items[] = {
+ { BEVEL_HN_NONE, "HN_NONE", 0, "Off", "Do not use Harden Normals" },
+ { BEVEL_HN_FACE, "HN_FACE", 0, "Face Area", "Use faces as weight" },
+ { BEVEL_HN_ADJ, "HN_ADJ", 0, "Vertex average", "Use adjacent vertices as weight" },
+ { 0, NULL, 0, NULL, NULL },
+ };
+
/* identifiers */
ot->name = "Bevel";
ot->description = "Edge Bevel";
@@ -666,6 +796,12 @@ void MESH_OT_bevel(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "clamp_overlap", false, "Clamp Overlap",
"Do not allow beveled edges/vertices to overlap each other");
RNA_def_boolean(ot->srna, "loop_slide", true, "Loop Slide", "Prefer slide along edge to even widths");
+ RNA_def_boolean(ot->srna, "mark_seam", false, "Mark Seams", "Mark Seams along beveled edges");
+ RNA_def_boolean(ot->srna, "mark_sharp", false, "Mark Sharp", "Mark beveled edges as sharp");
RNA_def_int(ot->srna, "material", -1, -1, INT_MAX, "Material",
"Material for bevel faces (-1 means use adjacent faces)", -1, 100);
+ RNA_def_float(ot->srna, "strength", 0.5f, 0.0f, 1.0f, "Normal Strength",
+ "Strength of calculated normal", 0.0f, 1.0f);
+ RNA_def_enum(ot->srna, "hnmode", harden_normals_items, BEVEL_HN_NONE, "Normal Mode",
+ "Weighting mode for Harden Normals");
}
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
index a9e11b7b411..9416d889a3b 100644
--- a/source/blender/editors/mesh/editmesh_bisect.c
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -70,7 +70,7 @@ typedef struct {
/* modal only */
BMBackup mesh_backup;
bool is_first;
- short mpr_flag;
+ short gizmo_flag;
} BisectData;
static bool mesh_bisect_interactive_calc(
@@ -156,8 +156,8 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* misc other vars */
G.moving = G_TRANSFORM_EDIT;
- opdata->mpr_flag = v3d->mpr_flag;
- v3d->mpr_flag = V3D_GIZMO_HIDE;
+ opdata->gizmo_flag = v3d->gizmo_flag;
+ v3d->gizmo_flag = V3D_GIZMO_HIDE;
/* initialize modal callout */
ED_workspace_status_text(C, IFACE_("LMB: Click and drag to draw cut line"));
@@ -169,7 +169,7 @@ static void edbm_bisect_exit(bContext *C, BisectData *opdata)
{
View3D *v3d = CTX_wm_view3d(C);
EDBM_redo_state_free(&opdata->mesh_backup, NULL, false);
- v3d->mpr_flag = opdata->mpr_flag;
+ v3d->gizmo_flag = opdata->gizmo_flag;
G.moving = 0;
}
@@ -199,8 +199,8 @@ static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Setup gizmos */
{
View3D *v3d = CTX_wm_view3d(C);
- if (v3d && (v3d->mpr_flag & V3D_GIZMO_HIDE) == 0) {
- WM_gizmo_group_type_ensure("MESH_WGT_bisect");
+ if (v3d && (v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
+ WM_gizmo_group_type_ensure("MESH_GGT_bisect");
}
}
#endif
@@ -334,7 +334,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
}
#ifdef USE_GIZMO
-static void MESH_WGT_bisect(struct wmGizmoGroupType *wgt);
+static void MESH_GGT_bisect(struct wmGizmoGroupType *gzgt);
#endif
void MESH_OT_bisect(struct wmOperatorType *ot)
@@ -374,7 +374,7 @@ void MESH_OT_bisect(struct wmOperatorType *ot)
WM_operator_properties_gesture_straightline(ot, CURSOR_EDIT);
#ifdef USE_GIZMO
- WM_gizmogrouptype_append(MESH_WGT_bisect);
+ WM_gizmogrouptype_append(MESH_GGT_bisect);
#endif
}
@@ -459,40 +459,40 @@ static void gizmo_mesh_bisect_update_from_op(GizmoGroup *man)
/* depth callbacks */
static void gizmo_bisect_prop_depth_get(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
void *value_p)
{
- GizmoGroup *man = mpr->parent_mgroup->customdata;
+ GizmoGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 1);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
float plane_co[3], plane_no[3];
RNA_property_float_get_array(op->ptr, man->data.prop_plane_co, plane_co);
RNA_property_float_get_array(op->ptr, man->data.prop_plane_no, plane_no);
- value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, mpr->matrix_basis[3]);
+ value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, gz->matrix_basis[3]);
}
static void gizmo_bisect_prop_depth_set(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
const void *value_p)
{
- GizmoGroup *man = mpr->parent_mgroup->customdata;
+ GizmoGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
const float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 1);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
float plane_co[3], plane[4];
RNA_property_float_get_array(op->ptr, man->data.prop_plane_co, plane_co);
RNA_property_float_get_array(op->ptr, man->data.prop_plane_no, plane);
normalize_v3(plane);
- plane[3] = -value[0] - dot_v3v3(plane, mpr->matrix_basis[3]);
+ plane[3] = -value[0] - dot_v3v3(plane, gz->matrix_basis[3]);
/* Keep our location, may be offset simply to be inside the viewport. */
closest_to_plane_normalized_v3(plane_co, plane, plane_co);
@@ -504,27 +504,27 @@ static void gizmo_bisect_prop_depth_set(
/* translate callbacks */
static void gizmo_bisect_prop_translate_get(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
void *value_p)
{
- GizmoGroup *man = mpr->parent_mgroup->customdata;
+ GizmoGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
- BLI_assert(mpr_prop->type->array_length == 3);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 3);
+ UNUSED_VARS_NDEBUG(gz_prop);
RNA_property_float_get_array(op->ptr, man->data.prop_plane_co, value_p);
}
static void gizmo_bisect_prop_translate_set(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
const void *value_p)
{
- GizmoGroup *man = mpr->parent_mgroup->customdata;
+ GizmoGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
- BLI_assert(mpr_prop->type->array_length == 3);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 3);
+ UNUSED_VARS_NDEBUG(gz_prop);
RNA_property_float_set_array(op->ptr, man->data.prop_plane_co, value_p);
@@ -533,15 +533,15 @@ static void gizmo_bisect_prop_translate_set(
/* angle callbacks */
static void gizmo_bisect_prop_angle_get(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
void *value_p)
{
- GizmoGroup *man = mpr->parent_mgroup->customdata;
+ GizmoGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 1);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
float plane_no[4];
RNA_property_float_get_array(op->ptr, man->data.prop_plane_no, plane_no);
@@ -560,15 +560,15 @@ static void gizmo_bisect_prop_angle_get(
}
static void gizmo_bisect_prop_angle_set(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
const void *value_p)
{
- GizmoGroup *man = mpr->parent_mgroup->customdata;
+ GizmoGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
const float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 1);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
float plane_no[4];
RNA_property_float_get_array(op->ptr, man->data.prop_plane_no, plane_no);
@@ -593,17 +593,17 @@ static void gizmo_bisect_prop_angle_set(
}
}
-static bool gizmo_mesh_bisect_poll(const bContext *C, wmGizmoGroupType *wgt)
+static bool gizmo_mesh_bisect_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
wmOperator *op = WM_operator_last_redo(C);
if (op == NULL || !STREQ(op->type->idname, "MESH_OT_bisect")) {
- WM_gizmo_group_type_unlink_delayed_ptr(wgt);
+ WM_gizmo_group_type_unlink_delayed_ptr(gzgt);
return false;
}
return true;
}
-static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *mgroup)
+static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
wmOperator *op = WM_operator_last_redo(C);
@@ -612,15 +612,15 @@ static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *mgroup)
}
struct GizmoGroup *man = MEM_callocN(sizeof(GizmoGroup), __func__);
- mgroup->customdata = man;
+ gzgroup->customdata = man;
- const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_3d", true);
- const wmGizmoType *wt_grab = WM_gizmotype_find("GIZMO_WT_grab_3d", true);
- const wmGizmoType *wt_dial = WM_gizmotype_find("GIZMO_WT_dial_3d", true);
+ const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
+ const wmGizmoType *gzt_grab = WM_gizmotype_find("GIZMO_GT_grab_3d", true);
+ const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
- man->translate_z = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL);
- man->translate_c = WM_gizmo_new_ptr(wt_grab, mgroup, NULL);
- man->rotate_c = WM_gizmo_new_ptr(wt_dial, mgroup, NULL);
+ man->translate_z = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ man->translate_c = WM_gizmo_new_ptr(gzt_grab, gzgroup, NULL);
+ man->rotate_c = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, man->translate_z->color);
UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, man->translate_c->color);
@@ -673,28 +673,28 @@ static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *mgroup)
}
static void gizmo_mesh_bisect_draw_prepare(
- const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+ const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- GizmoGroup *man = mgroup->customdata;
+ GizmoGroup *man = gzgroup->customdata;
if (man->data.op->next) {
man->data.op = WM_operator_last_redo((bContext *)man->data.context);
}
gizmo_mesh_bisect_update_from_op(man);
}
-static void MESH_WGT_bisect(struct wmGizmoGroupType *wgt)
+static void MESH_GGT_bisect(struct wmGizmoGroupType *gzgt)
{
- wgt->name = "Mesh Bisect";
- wgt->idname = "MESH_WGT_bisect";
+ gzgt->name = "Mesh Bisect";
+ gzgt->idname = "MESH_GGT_bisect";
- wgt->flag = WM_GIZMOGROUPTYPE_3D;
+ gzgt->flag = WM_GIZMOGROUPTYPE_3D;
- wgt->mmap_params.spaceid = SPACE_VIEW3D;
- wgt->mmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- wgt->poll = gizmo_mesh_bisect_poll;
- wgt->setup = gizmo_mesh_bisect_setup;
- wgt->draw_prepare = gizmo_mesh_bisect_draw_prepare;
+ gzgt->poll = gizmo_mesh_bisect_poll;
+ gzgt->setup = gizmo_mesh_bisect_setup;
+ gzgt->draw_prepare = gizmo_mesh_bisect_draw_prepare;
}
/** \} */
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index dd167c1fc15..c5ef2a06059 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -365,11 +365,11 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot)
#ifdef USE_GIZMO
-const float extrude_button_scale = 0.15f;
-const float extrude_button_offset_scale = 1.5f;
-const float extrude_arrow_scale = 1.0f;
-const float extrude_arrow_xyz_axis_scale = 1.0f;
-const float extrude_arrow_normal_axis_scale = 1.75f;
+static const float extrude_button_scale = 0.15f;
+static const float extrude_button_offset_scale = 1.5f;
+static const float extrude_arrow_scale = 1.0f;
+static const float extrude_arrow_xyz_axis_scale = 1.0f;
+static const float extrude_arrow_normal_axis_scale = 1.75f;
static const uchar shape_plus[] = {
0x5f, 0xfb, 0x40, 0xee, 0x25, 0xda, 0x11, 0xbf, 0x4, 0xa0, 0x0, 0x80, 0x4, 0x5f, 0x11,
@@ -417,31 +417,31 @@ static void gizmo_mesh_extrude_orientation_matrix_set(
}
}
-static bool gizmo_mesh_extrude_poll(const bContext *C, wmGizmoGroupType *wgt)
+static bool gizmo_mesh_extrude_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
ScrArea *sa = CTX_wm_area(C);
bToolRef_Runtime *tref_rt = sa->runtime.tool ? sa->runtime.tool->runtime : NULL;
if ((tref_rt == NULL) ||
- !STREQ(wgt->idname, tref_rt->gizmo_group) ||
+ !STREQ(gzgt->idname, tref_rt->gizmo_group) ||
!ED_operator_editmesh_view3d((bContext *)C))
{
- WM_gizmo_group_type_unlink_delayed_ptr(wgt);
+ WM_gizmo_group_type_unlink_delayed_ptr(gzgt);
return false;
}
return true;
}
-static void gizmo_mesh_extrude_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void gizmo_mesh_extrude_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
struct GizmoExtrudeGroup *man = MEM_callocN(sizeof(GizmoExtrudeGroup), __func__);
- mgroup->customdata = man;
+ gzgroup->customdata = man;
- const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_3d", true);
- const wmGizmoType *wt_grab = WM_gizmotype_find("GIZMO_WT_button_2d", true);
+ const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
+ const wmGizmoType *gzt_grab = WM_gizmotype_find("GIZMO_GT_button_2d", true);
for (int i = 0; i < 4; i++) {
- man->adjust_xyz_no[i] = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL);
- man->invoke_xyz_no[i] = WM_gizmo_new_ptr(wt_grab, mgroup, NULL);
+ man->adjust_xyz_no[i] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ man->invoke_xyz_no[i] = WM_gizmo_new_ptr(gzt_grab, gzgroup, NULL);
man->invoke_xyz_no[i]->flag |= WM_GIZMO_DRAW_OFFSET_SCALE;
}
@@ -503,9 +503,9 @@ static void gizmo_mesh_extrude_setup(const bContext *UNUSED(C), wmGizmoGroup *mg
}
}
-static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- GizmoExtrudeGroup *man = mgroup->customdata;
+ GizmoExtrudeGroup *man = gzgroup->customdata;
for (int i = 0; i < 4; i++) {
WM_gizmo_set_flag(man->invoke_xyz_no[i], WM_GIZMO_HIDDEN, true);
@@ -623,9 +623,9 @@ static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *mgroup)
}
}
-static void gizmo_mesh_extrude_draw_prepare(const bContext *C, wmGizmoGroup *mgroup)
+static void gizmo_mesh_extrude_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- GizmoExtrudeGroup *man = mgroup->customdata;
+ GizmoExtrudeGroup *man = gzgroup->customdata;
switch (man->data.orientation_type) {
case V3D_MANIP_VIEW:
{
@@ -640,38 +640,38 @@ static void gizmo_mesh_extrude_draw_prepare(const bContext *C, wmGizmoGroup *mgr
}
static void gizmo_mesh_extrude_message_subscribe(
- const bContext *C, wmGizmoGroup *mgroup, struct wmMsgBus *mbus)
+ const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
{
ARegion *ar = CTX_wm_region(C);
/* Subscribe to view properties */
- wmMsgSubscribeValue msg_sub_value_mpr_tag_refresh = {
+ wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
.owner = ar,
- .user_data = mgroup->parent_mmap,
+ .user_data = gzgroup->parent_gzmap,
.notify = WM_gizmo_do_msg_notify_tag_refresh,
};
{
- WM_msg_subscribe_rna_anon_prop(mbus, Scene, transform_orientation, &msg_sub_value_mpr_tag_refresh);
+ WM_msg_subscribe_rna_anon_prop(mbus, Scene, transform_orientation, &msg_sub_value_gz_tag_refresh);
}
}
-static void MESH_WGT_extrude(struct wmGizmoGroupType *wgt)
+static void MESH_GGT_extrude(struct wmGizmoGroupType *gzgt)
{
- wgt->name = "Mesh Extrude";
- wgt->idname = "MESH_WGT_extrude";
+ gzgt->name = "Mesh Extrude";
+ gzgt->idname = "MESH_GGT_extrude";
- wgt->flag = WM_GIZMOGROUPTYPE_3D;
+ gzgt->flag = WM_GIZMOGROUPTYPE_3D;
- wgt->mmap_params.spaceid = SPACE_VIEW3D;
- wgt->mmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- wgt->poll = gizmo_mesh_extrude_poll;
- wgt->setup = gizmo_mesh_extrude_setup;
- wgt->refresh = gizmo_mesh_extrude_refresh;
- wgt->draw_prepare = gizmo_mesh_extrude_draw_prepare;
- wgt->message_subscribe = gizmo_mesh_extrude_message_subscribe;
+ gzgt->poll = gizmo_mesh_extrude_poll;
+ gzgt->setup = gizmo_mesh_extrude_setup;
+ gzgt->refresh = gizmo_mesh_extrude_refresh;
+ gzgt->draw_prepare = gizmo_mesh_extrude_draw_prepare;
+ gzgt->message_subscribe = gizmo_mesh_extrude_message_subscribe;
}
#endif /* USE_GIZMO */
@@ -826,7 +826,7 @@ void MESH_OT_extrude_context(wmOperatorType *ot)
Transform_Properties(ot, P_NO_DEFAULTS | P_MIRROR_DUMMY);
#ifdef USE_GIZMO
- WM_gizmogrouptype_append(MESH_WGT_extrude);
+ WM_gizmogrouptype_append(MESH_GGT_extrude);
#endif
}
diff --git a/source/blender/editors/mesh/editmesh_extrude_spin.c b/source/blender/editors/mesh/editmesh_extrude_spin.c
index 3864bd63036..adb7ee71ee0 100644
--- a/source/blender/editors/mesh/editmesh_extrude_spin.c
+++ b/source/blender/editors/mesh/editmesh_extrude_spin.c
@@ -143,40 +143,40 @@ static void gizmo_mesh_spin_update_from_op(GizmoSpinGroup *man)
/* depth callbacks */
static void gizmo_spin_prop_depth_get(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
void *value_p)
{
- GizmoSpinGroup *man = mpr->parent_mgroup->customdata;
+ GizmoSpinGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 1);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
float plane_co[3], plane_no[3];
RNA_property_float_get_array(op->ptr, man->data.prop_axis_co, plane_co);
RNA_property_float_get_array(op->ptr, man->data.prop_axis_no, plane_no);
- value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, mpr->matrix_basis[3]);
+ value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, gz->matrix_basis[3]);
}
static void gizmo_spin_prop_depth_set(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
const void *value_p)
{
- GizmoSpinGroup *man = mpr->parent_mgroup->customdata;
+ GizmoSpinGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
const float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 1);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
float plane_co[3], plane[4];
RNA_property_float_get_array(op->ptr, man->data.prop_axis_co, plane_co);
RNA_property_float_get_array(op->ptr, man->data.prop_axis_no, plane);
normalize_v3(plane);
- plane[3] = -value[0] - dot_v3v3(plane, mpr->matrix_basis[3]);
+ plane[3] = -value[0] - dot_v3v3(plane, gz->matrix_basis[3]);
/* Keep our location, may be offset simply to be inside the viewport. */
closest_to_plane_normalized_v3(plane_co, plane, plane_co);
@@ -188,28 +188,28 @@ static void gizmo_spin_prop_depth_set(
/* translate callbacks */
static void gizmo_spin_prop_translate_get(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
void *value_p)
{
- GizmoSpinGroup *man = mpr->parent_mgroup->customdata;
+ GizmoSpinGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 3);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 3);
+ UNUSED_VARS_NDEBUG(gz_prop);
RNA_property_float_get_array(op->ptr, man->data.prop_axis_co, value);
}
static void gizmo_spin_prop_translate_set(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
const void *value)
{
- GizmoSpinGroup *man = mpr->parent_mgroup->customdata;
+ GizmoSpinGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
- BLI_assert(mpr_prop->type->array_length == 3);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 3);
+ UNUSED_VARS_NDEBUG(gz_prop);
RNA_property_float_set_array(op->ptr, man->data.prop_axis_co, value);
@@ -218,15 +218,15 @@ static void gizmo_spin_prop_translate_set(
/* angle callbacks */
static void gizmo_spin_prop_axis_angle_get(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
void *value_p)
{
- GizmoSpinGroup *man = mpr->parent_mgroup->customdata;
+ GizmoSpinGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 1);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
float plane_no[4];
RNA_property_float_get_array(op->ptr, man->data.prop_axis_no, plane_no);
@@ -245,15 +245,15 @@ static void gizmo_spin_prop_axis_angle_get(
}
static void gizmo_spin_prop_axis_angle_set(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
const void *value_p)
{
- GizmoSpinGroup *man = mpr->parent_mgroup->customdata;
+ GizmoSpinGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
const float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 1);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
float plane_no[4];
RNA_property_float_get_array(op->ptr, man->data.prop_axis_no, plane_no);
@@ -280,43 +280,43 @@ static void gizmo_spin_prop_axis_angle_set(
/* angle callbacks */
static void gizmo_spin_prop_angle_get(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
void *value_p)
{
- GizmoSpinGroup *man = mpr->parent_mgroup->customdata;
+ GizmoSpinGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 1);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
value[0] = RNA_property_float_get(op->ptr, man->data.prop_angle);
}
static void gizmo_spin_prop_angle_set(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
const void *value_p)
{
- GizmoSpinGroup *man = mpr->parent_mgroup->customdata;
+ GizmoSpinGroup *man = gz->parent_gzgroup->customdata;
wmOperator *op = man->data.op;
- BLI_assert(mpr_prop->type->array_length == 1);
- UNUSED_VARS_NDEBUG(mpr_prop);
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
const float *value = value_p;
RNA_property_float_set(op->ptr, man->data.prop_angle, value[0]);
gizmo_spin_exec(man);
}
-static bool gizmo_mesh_spin_poll(const bContext *C, wmGizmoGroupType *wgt)
+static bool gizmo_mesh_spin_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
wmOperator *op = WM_operator_last_redo(C);
if (op == NULL || !STREQ(op->type->idname, "MESH_OT_spin")) {
- WM_gizmo_group_type_unlink_delayed_ptr(wgt);
+ WM_gizmo_group_type_unlink_delayed_ptr(gzgt);
return false;
}
return true;
}
-static void gizmo_mesh_spin_setup(const bContext *C, wmGizmoGroup *mgroup)
+static void gizmo_mesh_spin_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
wmOperator *op = WM_operator_last_redo(C);
@@ -325,16 +325,16 @@ static void gizmo_mesh_spin_setup(const bContext *C, wmGizmoGroup *mgroup)
}
struct GizmoSpinGroup *man = MEM_callocN(sizeof(GizmoSpinGroup), __func__);
- mgroup->customdata = man;
+ gzgroup->customdata = man;
- const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_3d", true);
- const wmGizmoType *wt_grab = WM_gizmotype_find("GIZMO_WT_grab_3d", true);
- const wmGizmoType *wt_dial = WM_gizmotype_find("GIZMO_WT_dial_3d", true);
+ const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
+ const wmGizmoType *gzt_grab = WM_gizmotype_find("GIZMO_GT_grab_3d", true);
+ const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
- man->translate_z = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL);
- man->translate_c = WM_gizmo_new_ptr(wt_grab, mgroup, NULL);
- man->rotate_c = WM_gizmo_new_ptr(wt_dial, mgroup, NULL);
- man->angle_z = WM_gizmo_new_ptr(wt_dial, mgroup, NULL);
+ man->translate_z = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ man->translate_c = WM_gizmo_new_ptr(gzt_grab, gzgroup, NULL);
+ man->rotate_c = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
+ man->angle_z = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, man->translate_z->color);
UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, man->translate_c->color);
@@ -403,28 +403,28 @@ static void gizmo_mesh_spin_setup(const bContext *C, wmGizmoGroup *mgroup)
}
static void gizmo_mesh_spin_draw_prepare(
- const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+ const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- GizmoSpinGroup *man = mgroup->customdata;
+ GizmoSpinGroup *man = gzgroup->customdata;
if (man->data.op->next) {
man->data.op = WM_operator_last_redo((bContext *)man->data.context);
}
gizmo_mesh_spin_update_from_op(man);
}
-static void MESH_WGT_spin(struct wmGizmoGroupType *wgt)
+static void MESH_GGT_spin(struct wmGizmoGroupType *gzgt)
{
- wgt->name = "Mesh Spin";
- wgt->idname = "MESH_WGT_spin";
+ gzgt->name = "Mesh Spin";
+ gzgt->idname = "MESH_GGT_spin";
- wgt->flag = WM_GIZMOGROUPTYPE_3D;
+ gzgt->flag = WM_GIZMOGROUPTYPE_3D;
- wgt->mmap_params.spaceid = SPACE_VIEW3D;
- wgt->mmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- wgt->poll = gizmo_mesh_spin_poll;
- wgt->setup = gizmo_mesh_spin_setup;
- wgt->draw_prepare = gizmo_mesh_spin_draw_prepare;
+ gzgt->poll = gizmo_mesh_spin_poll;
+ gzgt->setup = gizmo_mesh_spin_setup;
+ gzgt->draw_prepare = gizmo_mesh_spin_draw_prepare;
}
/** \} */
@@ -511,8 +511,8 @@ static int edbm_spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e
#ifdef USE_GIZMO
if (ret & OPERATOR_FINISHED) {
/* Setup gizmos */
- if (v3d && ((v3d->mpr_flag & V3D_GIZMO_HIDE) == 0)) {
- WM_gizmo_group_type_ensure("MESH_WGT_spin");
+ if (v3d && ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0)) {
+ WM_gizmo_group_type_ensure("MESH_GGT_spin");
}
}
#endif
@@ -549,6 +549,6 @@ void MESH_OT_spin(wmOperatorType *ot)
RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -1.0f, 1.0f);
#ifdef USE_GIZMO
- WM_gizmogrouptype_append(MESH_WGT_spin);
+ WM_gizmogrouptype_append(MESH_GGT_spin);
#endif
}
diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c
index 1be180b852c..486203462a0 100644
--- a/source/blender/editors/mesh/editmesh_inset.c
+++ b/source/blender/editors/mesh/editmesh_inset.c
@@ -78,7 +78,7 @@ typedef struct {
/* modal only */
float mcenter[2];
void *draw_handle_pixel;
- short mpr_flag;
+ short gizmo_flag;
} InsetData;
@@ -173,8 +173,8 @@ static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal)
ar->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL);
G.moving = G_TRANSFORM_EDIT;
if (v3d) {
- opdata->mpr_flag = v3d->mpr_flag;
- v3d->mpr_flag = V3D_GIZMO_HIDE;
+ opdata->gizmo_flag = v3d->gizmo_flag;
+ v3d->gizmo_flag = V3D_GIZMO_HIDE;
}
}
@@ -196,7 +196,7 @@ static void edbm_inset_exit(bContext *C, wmOperator *op)
}
ED_region_draw_cb_exit(ar->type, opdata->draw_handle_pixel);
if (v3d) {
- v3d->mpr_flag = opdata->mpr_flag;
+ v3d->gizmo_flag = opdata->gizmo_flag;
}
G.moving = 0;
}
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 8a9a5eadbdd..c98aef74ae7 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1007,13 +1007,13 @@ static void knifetool_draw_angle_snapping(const KnifeTool_OpData *kcd)
copy_v3_v3(v2, ray_hit_best[1]);
}
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformThemeColor(TH_TRANSFORM);
GPU_line_width(2.0);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(pos, v1);
immVertex3fv(pos, v2);
immEnd();
@@ -1040,26 +1040,27 @@ static void knife_init_colors(KnifeColors *colors)
static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
{
const KnifeTool_OpData *kcd = arg;
-
GPU_depth_test(false);
glPolygonOffset(1.0f, 1.0f);
- gpuPushMatrix();
- gpuMultMatrix(kcd->ob->obmat);
+ GPU_matrix_push();
+ GPU_matrix_mul(kcd->ob->obmat);
+
+ if (kcd->mode == MODE_DRAGGING && kcd->is_angle_snapping) {
+ knifetool_draw_angle_snapping(kcd);
+ }
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
if (kcd->mode == MODE_DRAGGING) {
- if (kcd->is_angle_snapping)
- knifetool_draw_angle_snapping(kcd);
-
immUniformColor3ubv(kcd->colors.line);
GPU_line_width(2.0);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(pos, kcd->prev.cage);
immVertex3fv(pos, kcd->curr.cage);
immEnd();
@@ -1069,7 +1070,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
immUniformColor3ubv(kcd->colors.point);
GPU_point_size(11);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex3fv(pos, kcd->prev.cage);
immEnd();
}
@@ -1078,7 +1079,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
immUniformColor3ubv(kcd->colors.curpoint);
GPU_point_size(9);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex3fv(pos, kcd->prev.cage);
immEnd();
}
@@ -1087,7 +1088,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
immUniformColor3ubv(kcd->colors.edge);
GPU_line_width(2.0);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(pos, kcd->curr.edge->v1->cageco);
immVertex3fv(pos, kcd->curr.edge->v2->cageco);
immEnd();
@@ -1096,7 +1097,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
immUniformColor3ubv(kcd->colors.point);
GPU_point_size(11);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex3fv(pos, kcd->curr.cage);
immEnd();
}
@@ -1105,47 +1106,50 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
immUniformColor3ubv(kcd->colors.curpoint);
GPU_point_size(9);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex3fv(pos, kcd->curr.cage);
immEnd();
}
if (kcd->totlinehit > 0) {
KnifeLineHit *lh;
- int i;
+ int i, v, vs;
+ float fcol[4];
GPU_blend(true);
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- /* draw any snapped verts first */
- immUniformColor4ubv(kcd->colors.point_a);
- GPU_point_size(11);
-
- immBeginAtMost(GWN_PRIM_POINTS, kcd->totlinehit);
+ GPUVertBuf *vert = GPU_vertbuf_create_with_format(format);
+ GPU_vertbuf_data_alloc(vert, kcd->totlinehit);
lh = kcd->linehits;
- for (i = 0; i < kcd->totlinehit; i++, lh++) {
+ for (i = 0, v = 0, vs = kcd->totlinehit - 1; i < kcd->totlinehit; i++, lh++) {
if (lh->v) {
- immVertex3fv(pos, lh->cagehit);
+ GPU_vertbuf_attr_set(vert, pos, v++, lh->cagehit);
+ }
+ else {
+ GPU_vertbuf_attr_set(vert, pos, vs--, lh->cagehit);
}
}
- immEnd();
+ GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vert, NULL, GPU_BATCH_OWNS_VBO);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+
+ /* draw any snapped verts first */
+ rgba_uchar_to_float(fcol, kcd->colors.point_a);
+ GPU_batch_uniform_4fv(batch, "color", fcol);
+ GPU_matrix_bind(batch->interface);
+ GPU_point_size(11);
+ GPU_batch_draw_range_ex(batch, 0, v - 1, false);
/* now draw the rest */
- immUniformColor4ubv(kcd->colors.curpoint_a);
+ rgba_uchar_to_float(fcol, kcd->colors.curpoint_a);
+ GPU_batch_uniform_4fv(batch, "color", fcol);
GPU_point_size(7);
+ GPU_batch_draw_range_ex(batch, vs + 1, kcd->totlinehit - (vs + 1), false);
- immBeginAtMost(GWN_PRIM_POINTS, kcd->totlinehit);
-
- lh = kcd->linehits;
- for (i = 0; i < kcd->totlinehit; i++, lh++) {
- if (!lh->v) {
- immVertex3fv(pos, lh->cagehit);
- }
- }
-
- immEnd();
+ GPU_batch_program_use_end(batch);
+ GPU_batch_discard(batch);
GPU_blend(false);
}
@@ -1157,7 +1161,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
immUniformColor3ubv(kcd->colors.line);
GPU_line_width(1.0);
- immBeginAtMost(GWN_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2);
+ GPUBatch *batch = immBeginBatchAtMost(GPU_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2);
BLI_mempool_iternew(kcd->kedges, &iter);
for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) {
@@ -1169,6 +1173,9 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
}
immEnd();
+
+ GPU_batch_draw(batch);
+ GPU_batch_discard(batch);
}
if (kcd->totkvert > 0) {
@@ -1178,7 +1185,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
immUniformColor3ubv(kcd->colors.point);
GPU_point_size(5.0);
- immBeginAtMost(GWN_PRIM_POINTS, BLI_mempool_len(kcd->kverts));
+ GPUBatch *batch = immBeginBatchAtMost(GPU_PRIM_POINTS, BLI_mempool_len(kcd->kverts));
BLI_mempool_iternew(kcd->kverts, &iter);
for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) {
@@ -1189,11 +1196,14 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
}
immEnd();
+
+ GPU_batch_draw(batch);
+ GPU_batch_discard(batch);
}
immUnbindProgram();
- gpuPopMatrix();
+ GPU_matrix_pop();
/* Reset default */
GPU_depth_test(true);
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 87c006095ed..95c94c146e4 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -113,16 +113,16 @@ static void ringsel_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *a
if ((lcd->totedge > 0) || (lcd->totpoint > 0)) {
GPU_depth_test(false);
- gpuPushMatrix();
- gpuMultMatrix(lcd->ob->obmat);
+ GPU_matrix_push();
+ GPU_matrix_mul(lcd->ob->obmat);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor3ub(255, 0, 255);
if (lcd->totedge > 0) {
- immBegin(GWN_PRIM_LINES, lcd->totedge * 2);
+ immBegin(GPU_PRIM_LINES, lcd->totedge * 2);
for (int i = 0; i < lcd->totedge; i++) {
immVertex3fv(pos, lcd->edges[i][0]);
@@ -135,7 +135,7 @@ static void ringsel_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *a
if (lcd->totpoint > 0) {
GPU_point_size(3.0f);
- immBegin(GWN_PRIM_POINTS, lcd->totpoint);
+ immBegin(GPU_PRIM_POINTS, lcd->totpoint);
for (int i = 0; i < lcd->totpoint; i++) {
immVertex3fv(pos, lcd->points[i]);
@@ -146,7 +146,7 @@ static void ringsel_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *a
immUnbindProgram();
- gpuPopMatrix();
+ GPU_matrix_pop();
/* Reset default */
GPU_depth_test(true);
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 2e7cf1fc76f..cdb8981801a 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -1462,6 +1462,18 @@ static int edbm_select_mode_exec(bContext *C, wmOperator *op)
static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ /* Bypass when in UV non sync-select mode, fall through to keymap that edits. */
+ if (CTX_wm_space_image(C)) {
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ if ((ts->uv_flag & UV_SYNC_SELECTION) == 0) {
+ return OPERATOR_PASS_THROUGH;
+ }
+ /* Bypass when no action is needed. */
+ if (!RNA_struct_property_is_set(op->ptr, "type")) {
+ return OPERATOR_CANCELLED;
+ }
+ }
+
/* detecting these options based on shift/ctrl here is weak, but it's done
* to make this work when clicking buttons or menus */
if (!RNA_struct_property_is_set(op->ptr, "use_extend"))
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index d7617a14ff3..76ba2e5c67e 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -41,11 +41,16 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BLI_bitmap.h"
+#include "BLI_heap.h"
#include "BLI_listbase.h"
+#include "BLI_linklist.h"
+#include "BLI_linklist_stack.h"
#include "BLI_noise.h"
#include "BLI_math.h"
#include "BLI_rand.h"
#include "BLI_sort_utils.h"
+#include "BLI_string.h"
#include "BKE_layer.h"
#include "BKE_material.h"
@@ -54,6 +59,7 @@
#include "BKE_report.h"
#include "BKE_texture.h"
#include "BKE_main.h"
+#include "BKE_mesh.h"
#include "BKE_editmesh.h"
#include "DEG_depsgraph.h"
@@ -6001,10 +6007,10 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+static bool edbm_sort_elements_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
{
const char *prop_id = RNA_property_identifier(prop);
- const int action = RNA_enum_get(ptr, "type");
+ const int action = RNA_enum_get(op->ptr, "type");
/* Only show seed for randomize action! */
if (STREQ(prop_id, "seed")) {
@@ -6025,18 +6031,6 @@ static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *pro
return true;
}
-static void edbm_sort_elements_ui(bContext *C, wmOperator *op)
-{
- uiLayout *layout = op->layout;
- wmWindowManager *wm = CTX_wm_manager(C);
- PointerRNA ptr;
-
- RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-
- /* Main auto-draw call. */
- uiDefAutoButsRNA(layout, &ptr, edbm_sort_elements_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
-}
-
void MESH_OT_sort_elements(wmOperatorType *ot)
{
static const EnumPropertyItem type_items[] = {
@@ -6072,7 +6066,7 @@ void MESH_OT_sort_elements(wmOperatorType *ot)
ot->invoke = WM_menu_invoke;
ot->exec = edbm_sort_elements_exec;
ot->poll = ED_operator_editmesh;
- ot->ui = edbm_sort_elements_ui;
+ ot->poll_property = edbm_sort_elements_poll_property;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -6924,3 +6918,1339 @@ void MESH_OT_mark_freestyle_face(wmOperatorType *ot)
/** \} */
#endif /* WITH_FREESTYLE */
+
+/********************** Loop normals editing tools modal map. **********************/
+
+/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
+/* NOTE: We could add more here, like e.g. a switch between local or global coordinates of target,
+ * use numinput to type in explicit vector values... */
+enum {
+ /* Generic commands. */
+ EDBM_CLNOR_MODAL_CANCEL = 1,
+ EDBM_CLNOR_MODAL_CONFIRM = 2,
+
+ /* Point To operator. */
+ EDBM_CLNOR_MODAL_POINTTO_RESET = 101,
+ EDBM_CLNOR_MODAL_POINTTO_INVERT = 102,
+ EDBM_CLNOR_MODAL_POINTTO_SPHERIZE = 103,
+ EDBM_CLNOR_MODAL_POINTTO_ALIGN = 104,
+
+ EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE = 110,
+ EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT = 111,
+ EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT = 112,
+ EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR = 113,
+ EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED = 114,
+};
+
+/* called in transform_ops.c, on each regeneration of keymaps */
+wmKeyMap *point_normals_modal_keymap(wmKeyConfig *keyconf)
+{
+ static const EnumPropertyItem modal_items[] = {
+ {EDBM_CLNOR_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+ {EDBM_CLNOR_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+
+ /* Point To operator. */
+ {EDBM_CLNOR_MODAL_POINTTO_RESET, "RESET", 0, "Reset", "Reset normals to initial ones"},
+ {EDBM_CLNOR_MODAL_POINTTO_INVERT, "INVERT", 0, "Invert", "Toggle inversion of affected normals"},
+ {EDBM_CLNOR_MODAL_POINTTO_SPHERIZE, "SPHERIZE", 0, "Spherize", "Interpolate between new and original normals"},
+ {EDBM_CLNOR_MODAL_POINTTO_ALIGN, "ALIGN", 0, "Align", "Make all affected normals parallel"},
+
+ {EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE, "USE_MOUSE", 0, "Use Mouse", "Follow mouse cursor position"},
+ {EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT, "USE_PIVOT", 0, "Use Pivot",
+ "Use current rotation/scaling pivot point coordinates"},
+ {EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT, "USE_OBJECT", 0, "Use Object", "Use current edited object's location"},
+ {EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR, "SET_USE_3DCURSOR", 0, "Set and Use 3D Cursor",
+ "Set new 3D cursor position and use it"},
+ {EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED, "SET_USE_SELECTED", 0, "Select and Use Mesh Item",
+ "Select new active mesh element and use its location"},
+ {0, NULL, 0, NULL, NULL}
+ };
+ static const char *keymap_name = "Custom Normals Modal Map";
+
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, keymap_name);
+
+ /* We only need to add map once */
+ if (keymap && keymap->modal_items)
+ return NULL;
+
+ keymap = WM_modalkeymap_add(keyconf, keymap_name, modal_items);
+
+ /* Generic items for modal map. */
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, EDBM_CLNOR_MODAL_CANCEL);
+ WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_CANCEL);
+
+ WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, EDBM_CLNOR_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, EDBM_CLNOR_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_CONFIRM);
+
+ /* Point To items for modal map */
+ WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_RESET);
+ WM_modalkeymap_add_item(keymap, IKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_INVERT);
+ WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_SPHERIZE);
+ WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_ALIGN);
+
+ WM_modalkeymap_add_item(keymap, MKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE);
+ WM_modalkeymap_add_item(keymap, LKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT);
+ WM_modalkeymap_add_item(keymap, OKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT);
+
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_CLICK, KM_CTRL, 0, EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR);
+ WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_CLICK, KM_CTRL, 0, EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED);
+
+ WM_modalkeymap_assign(keymap, "MESH_OT_point_normals");
+
+ return keymap;
+}
+
+#define CLNORS_VALID_VEC_LEN (1e-4f)
+
+/********************** 'Point to' Loop Normals **********************/
+
+enum {
+ EDBM_CLNOR_POINTTO_MODE_COORDINATES = 1,
+ EDBM_CLNOR_POINTTO_MODE_MOUSE = 2,
+};
+
+static EnumPropertyItem clnors_pointto_mode_items[] = {
+ {EDBM_CLNOR_POINTTO_MODE_COORDINATES, "COORDINATES", 0, "Coordinates",
+ "Use static coordinates (defined by various means)"},
+ {EDBM_CLNOR_POINTTO_MODE_MOUSE, "MOUSE", 0, "Mouse", "Follow mouse cursor"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+/* Initialize loop normal data */
+static int point_normals_init(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+
+ BKE_editmesh_lnorspace_update(em);
+ BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
+
+ op->customdata = lnors_ed_arr;
+
+ return lnors_ed_arr->totloop;
+}
+
+static void point_normals_free(bContext *C, wmOperator *op)
+{
+ BMLoopNorEditDataArray *lnors_ed_arr = op->customdata;
+ BM_loop_normal_editdata_array_free(lnors_ed_arr);
+ op->customdata = NULL;
+ ED_area_status_text(CTX_wm_area(C), NULL);
+}
+
+static void point_normals_update_header(bContext *C, wmOperator *op)
+{
+ char header[UI_MAX_DRAW_STR];
+ char buf[UI_MAX_DRAW_STR];
+
+ char *p = buf;
+ int available_len = sizeof(buf);
+
+#define WM_MODALKEY(_id) \
+ WM_modalkeymap_operator_items_to_string_buf(op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p)
+
+ BLI_snprintf(header, sizeof(header), IFACE_("%s: confirm, %s: cancel, "
+ "%s: point to mouse (%s), %s: point to Pivot, "
+ "%s: point to object origin, %s: reset normals, "
+ "%s: set & point to 3D cursor, %s: select & point to mesh item, "
+ "%s: invert normals (%s), %s: spherize (%s), %s: align (%s)"),
+ WM_MODALKEY(EDBM_CLNOR_MODAL_CONFIRM), WM_MODALKEY(EDBM_CLNOR_MODAL_CANCEL),
+ WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE),
+ WM_bool_as_string(RNA_enum_get(op->ptr, "mode") == EDBM_CLNOR_POINTTO_MODE_MOUSE),
+ WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT),
+ WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_RESET), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR),
+ WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED),
+ WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_INVERT), WM_bool_as_string(RNA_boolean_get(op->ptr, "invert")),
+ WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SPHERIZE),
+ WM_bool_as_string(RNA_boolean_get(op->ptr, "spherize")),
+ WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_ALIGN), WM_bool_as_string(RNA_boolean_get(op->ptr, "align")));
+
+#undef WM_MODALKEY
+
+ ED_area_status_text(CTX_wm_area(C), header);
+}
+
+/* TODO move that to generic function in BMesh? */
+static void bmesh_selected_verts_center_calc(BMesh *bm, float *r_center)
+{
+ BMVert *v;
+ BMIter viter;
+ int i = 0;
+
+ zero_v3(r_center);
+ BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ add_v3_v3(r_center, v->co);
+ i++;
+ }
+ }
+ mul_v3_fl(r_center, 1.0f / (float)i);
+}
+
+static void point_normals_apply(bContext *C, wmOperator *op, float target[3], const bool do_reset)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMesh *bm = BKE_editmesh_from_object(obedit)->bm;
+ BMLoopNorEditDataArray *lnors_ed_arr = op->customdata;
+
+ const bool do_invert = RNA_boolean_get(op->ptr, "invert");
+ const bool do_spherize = RNA_boolean_get(op->ptr, "spherize");
+ const bool do_align = RNA_boolean_get(op->ptr, "align");
+ float center[3];
+
+ if (do_align && !do_reset) {
+ bmesh_selected_verts_center_calc(bm, center);
+ }
+
+ sub_v3_v3(target, obedit->loc); /* Move target to local coordinates. */
+
+ BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
+ if (do_reset) {
+ copy_v3_v3(lnor_ed->nloc, lnor_ed->niloc);
+ }
+ else if (do_spherize) {
+ /* Note that this is *not* real spherical interpolation. Probably good enough in this case though? */
+ const float strength = RNA_float_get(op->ptr, "spherize_strength");
+ float spherized_normal[3];
+
+ sub_v3_v3v3(spherized_normal, target, lnor_ed->loc);
+ normalize_v3(spherized_normal); /* otherwise, multiplication by strength is meaningless... */
+ mul_v3_fl(spherized_normal, strength);
+ mul_v3_v3fl(lnor_ed->nloc, lnor_ed->niloc, 1.0f - strength);
+ add_v3_v3(lnor_ed->nloc, spherized_normal);
+ }
+ else if (do_align) {
+ sub_v3_v3v3(lnor_ed->nloc, target, center);
+ }
+ else {
+ sub_v3_v3v3(lnor_ed->nloc, target, lnor_ed->loc);
+ }
+
+ if (do_invert && !do_reset) {
+ negate_v3(lnor_ed->nloc);
+ }
+ if (normalize_v3(lnor_ed->nloc) >= CLNORS_VALID_VEC_LEN) {
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data);
+ }
+ }
+}
+
+static int edbm_point_normals_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+
+ float target[3];
+
+ int ret = OPERATOR_PASS_THROUGH;
+ int mode = RNA_enum_get(op->ptr, "mode");
+ int new_mode = mode;
+ bool force_mousemove = false;
+ bool do_reset = false;
+
+ PropertyRNA *prop_target = RNA_struct_find_property(op->ptr, "target_location");
+
+ if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case EDBM_CLNOR_MODAL_CONFIRM:
+ RNA_property_float_get_array(op->ptr, prop_target, target);
+ ret = OPERATOR_FINISHED;
+ break;
+
+ case EDBM_CLNOR_MODAL_CANCEL:
+ do_reset = true;
+ ret = OPERATOR_CANCELLED;
+ break;
+
+ case EDBM_CLNOR_MODAL_POINTTO_RESET:
+ do_reset = true;
+ ret = OPERATOR_RUNNING_MODAL;
+ break;
+
+ case EDBM_CLNOR_MODAL_POINTTO_INVERT:
+ {
+ PropertyRNA *prop_invert = RNA_struct_find_property(op->ptr, "invert");
+ RNA_property_boolean_set(op->ptr, prop_invert, !RNA_property_boolean_get(op->ptr, prop_invert));
+ RNA_property_float_get_array(op->ptr, prop_target, target);
+ ret = OPERATOR_RUNNING_MODAL;
+ break;
+ }
+
+ case EDBM_CLNOR_MODAL_POINTTO_SPHERIZE:
+ {
+ PropertyRNA *prop_spherize = RNA_struct_find_property(op->ptr, "spherize");
+ RNA_property_boolean_set(op->ptr, prop_spherize, !RNA_property_boolean_get(op->ptr, prop_spherize));
+ RNA_property_float_get_array(op->ptr, prop_target, target);
+ ret = OPERATOR_RUNNING_MODAL;
+ break;
+ }
+
+ case EDBM_CLNOR_MODAL_POINTTO_ALIGN:
+ {
+ PropertyRNA *prop_align = RNA_struct_find_property(op->ptr, "align");
+ RNA_property_boolean_set(op->ptr, prop_align, !RNA_property_boolean_get(op->ptr, prop_align));
+ RNA_property_float_get_array(op->ptr, prop_target, target);
+ ret = OPERATOR_RUNNING_MODAL;
+ break;
+ }
+
+ case EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE:
+ new_mode = EDBM_CLNOR_POINTTO_MODE_MOUSE;
+ force_mousemove = true; /* We want to immediately update to mouse cursor position... */
+ ret = OPERATOR_RUNNING_MODAL;
+ break;
+
+ case EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT:
+ new_mode = EDBM_CLNOR_POINTTO_MODE_COORDINATES;
+ copy_v3_v3(target, obedit->loc);
+ ret = OPERATOR_RUNNING_MODAL;
+ break;
+
+ case EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR:
+ new_mode = EDBM_CLNOR_POINTTO_MODE_COORDINATES;
+ ED_view3d_cursor3d_update(C, event->mval, false, V3D_CURSOR_ORIENT_NONE);
+ copy_v3_v3(target, ED_view3d_cursor3d_get(scene, v3d)->location);
+ break;
+
+ case EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED:
+ new_mode = EDBM_CLNOR_POINTTO_MODE_COORDINATES;
+ view3d_operator_needs_opengl(C);
+ if (EDBM_select_pick(C, event->mval, false, false, false)) {
+ ED_object_editmode_calc_active_center(obedit, false, target); /* Point to newly selected active. */
+ add_v3_v3(target, obedit->loc);
+ ret = OPERATOR_RUNNING_MODAL;
+ }
+ break;
+
+ case EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT:
+ new_mode = EDBM_CLNOR_POINTTO_MODE_COORDINATES;
+ switch (scene->toolsettings->transform_pivot_point) {
+ case V3D_AROUND_CENTER_BOUNDS: /* calculateCenterBound */
+ {
+ BMVert *v;
+ BMIter viter;
+ float min[3], max[3];
+ int i = 0;
+
+ BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ if (i) {
+ minmax_v3v3_v3(min, max, v->co);
+ }
+ else {
+ copy_v3_v3(min, v->co);
+ copy_v3_v3(max, v->co);
+ }
+ i++;
+ }
+ }
+ mid_v3_v3v3(target, min, max);
+ add_v3_v3(target, obedit->loc);
+ break;
+ }
+
+ case V3D_AROUND_CENTER_MEAN:
+ {
+ bmesh_selected_verts_center_calc(bm, target);
+ add_v3_v3(target, obedit->loc);
+ break;
+ }
+
+ case V3D_AROUND_CURSOR:
+ copy_v3_v3(target, ED_view3d_cursor3d_get(scene, v3d)->location);
+ break;
+
+ case V3D_AROUND_ACTIVE:
+ if (!ED_object_editmode_calc_active_center(obedit, false, target)) {
+ zero_v3(target);
+ }
+ add_v3_v3(target, obedit->loc);
+ break;
+
+ default:
+ BKE_report(op->reports, RPT_WARNING, "Does not support Individual Origin as pivot");
+ copy_v3_v3(target, obedit->loc);
+ }
+ ret = OPERATOR_RUNNING_MODAL;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (new_mode != mode) {
+ mode = new_mode;
+ RNA_enum_set(op->ptr, "mode", mode);
+ }
+
+ /* Only handle mousemove event in case we are in mouse mode. */
+ if (event->type == MOUSEMOVE || force_mousemove) {
+ if (mode == EDBM_CLNOR_POINTTO_MODE_MOUSE) {
+ ARegion *ar = CTX_wm_region(C);
+ float center[3];
+
+ bmesh_selected_verts_center_calc(bm, center);
+
+ ED_view3d_win_to_3d_int(v3d, ar, center, event->mval, target);
+
+ ret = OPERATOR_RUNNING_MODAL;
+ }
+ }
+
+ if (ret != OPERATOR_PASS_THROUGH) {
+ if (!ELEM(ret, OPERATOR_CANCELLED, OPERATOR_FINISHED)) {
+ RNA_property_float_set_array(op->ptr, prop_target, target);
+ }
+ point_normals_apply(C, op, target, do_reset);
+ EDBM_update_generic(em, true, false); /* Recheck bools. */
+
+ point_normals_update_header(C, op);
+ }
+
+ if (ELEM(ret, OPERATOR_CANCELLED, OPERATOR_FINISHED)) {
+ point_normals_free(C, op);
+ }
+
+ return ret;
+}
+
+static int edbm_point_normals_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ if (!point_normals_init(C, op, event)) {
+ point_normals_free(C, op);
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_event_add_modal_handler(C, op);
+
+ point_normals_update_header(C, op);
+
+ op->flag |= OP_IS_MODAL_GRAB_CURSOR;
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int edbm_point_normals_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ if (!point_normals_init(C, op, NULL)) {
+ point_normals_free(C, op);
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Note that 'mode' is ignored in exec case, we directly use vector stored in target_location, whatever that is. */
+
+ float target[3];
+ RNA_float_get_array(op->ptr, "target_location", target);
+
+ point_normals_apply(C, op, target, false);
+
+ EDBM_update_generic(em, true, false);
+ point_normals_free(C, op);
+
+ return OPERATOR_FINISHED;
+}
+
+static bool point_normals_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data))
+{
+ const char *prop_id = RNA_property_identifier(prop);
+
+ /* Only show strength option if spherize is enabled. */
+ if (STREQ(prop_id, "spherize_strength")) {
+ return (bool)RNA_boolean_get(ptr, "spherize");
+ }
+
+ /* Else, show it! */
+ return true;
+}
+
+static void edbm_point_normals_ui(bContext *C, wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ PointerRNA ptr;
+
+ RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+
+ /* Main auto-draw call */
+ uiDefAutoButsRNA(layout, &ptr, point_normals_draw_check_prop, NULL, '\0', false);
+}
+
+void MESH_OT_point_normals(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Point Normals to Target";
+ ot->description = "Point selected custom normals to specified Target";
+ ot->idname = "MESH_OT_point_normals";
+
+ /* api callbacks */
+ ot->exec = edbm_point_normals_exec;
+ ot->invoke = edbm_point_normals_invoke;
+ ot->modal = edbm_point_normals_modal;
+ ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->ui = edbm_point_normals_ui;
+ ot->cancel = point_normals_free;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_enum(ot->srna, "mode", clnors_pointto_mode_items, EDBM_CLNOR_POINTTO_MODE_COORDINATES,
+ "Mode", "How to define coordinates to point custom normals to");
+ RNA_def_property_flag(ot->prop, PROP_HIDDEN);
+
+ RNA_def_boolean(ot->srna, "invert", false, "Invert", "Invert affected normals");
+
+ RNA_def_boolean(ot->srna, "align", false, "Align", "Make all affected normals parallel");
+
+ RNA_def_float_vector(ot->srna, "target_location", 3, (float[3]){0.0f, 0.0f, 0.0f}, -FLT_MAX, FLT_MAX,
+ "Target", "Target location to which normals will point", -1000.0f, 1000.0f);
+
+ RNA_def_boolean(ot->srna, "spherize", false,
+ "Spherize", "Interpolate between original and new normals");
+
+ RNA_def_float(ot->srna, "spherize_strength", 0.1, 0.0f, 1.0f,
+ "Spherize Strength", "Ratio of spherized normal to original normal", 0.0f, 1.0f);
+}
+
+/********************** Split/Merge Loop Normals **********************/
+
+static void normals_merge(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr)
+{
+ BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
+
+ BLI_SMALLSTACK_DECLARE(clnors, short *);
+
+ BLI_assert(bm->lnor_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR);
+
+ BM_normals_loops_edges_tag(bm, false);
+
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
+ if (BM_elem_flag_test(lnor_ed->loop, BM_ELEM_TAG)) {
+ continue;
+ }
+
+ MLoopNorSpace *lnor_space = bm->lnor_spacearr->lspacearr[lnor_ed->loop_index];
+
+ if ((lnor_space->flags & MLNOR_SPACE_IS_SINGLE) == 0) {
+ LinkNode *loops = lnor_space->loops;
+ float avg_normal[3] = {0.0f, 0.0f, 0.0f};
+ short *clnors_data;
+
+ for (; loops; loops = loops->next) {
+ BMLoop *l = loops->link;
+ const int loop_index = BM_elem_index_get(l);
+
+ BMLoopNorEditData *lnor_ed_tmp = lnors_ed_arr->lidx_to_lnor_editdata[loop_index];
+ BLI_assert(lnor_ed_tmp->loop_index == loop_index && lnor_ed_tmp->loop == l);
+ add_v3_v3(avg_normal, lnor_ed_tmp->nloc);
+ BLI_SMALLSTACK_PUSH(clnors, lnor_ed_tmp->clnors_data);
+ BM_elem_flag_enable(l, BM_ELEM_TAG);
+ }
+ if (normalize_v3(avg_normal) < CLNORS_VALID_VEC_LEN) {
+ /* If avg normal is nearly 0, set clnor to default value. */
+ zero_v3(avg_normal);
+ }
+ while ((clnors_data = BLI_SMALLSTACK_POP(clnors))) {
+ BKE_lnor_space_custom_normal_to_data(lnor_space, avg_normal, clnors_data);
+ }
+ }
+ }
+}
+
+static void normals_split(BMesh *bm)
+{
+ BMFace *f;
+ BMLoop *l, *l_curr, *l_first;
+ BMIter fiter;
+
+ BLI_assert(bm->lnor_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR);
+
+ BM_normals_loops_edges_tag(bm, true);
+
+ const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ l_curr = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_curr->v, BM_ELEM_SELECT) && (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) ||
+ (!BM_elem_flag_test(l_curr, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_curr))))
+ {
+ if (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) && !BM_elem_flag_test(l_curr->prev->e, BM_ELEM_TAG)) {
+ const int loop_index = BM_elem_index_get(l_curr);
+ short *clnors = BM_ELEM_CD_GET_VOID_P(l_curr, cd_clnors_offset);
+ BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], f->no, clnors);
+ }
+ else {
+ BMVert *v_pivot = l_curr->v;
+ BMEdge *e_next;
+ const BMEdge *e_org = l_curr->e;
+ BMLoop *lfan_pivot, *lfan_pivot_next;
+
+ lfan_pivot = l_curr;
+ e_next = lfan_pivot->e;
+ BLI_SMALLSTACK_DECLARE(loops, BMLoop *);
+ float avg_normal[3] = { 0.0f };
+
+ while (true) {
+ lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next);
+ if (lfan_pivot_next) {
+ BLI_assert(lfan_pivot_next->v == v_pivot);
+ }
+ else {
+ e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e;
+ }
+
+ BLI_SMALLSTACK_PUSH(loops, lfan_pivot);
+ add_v3_v3(avg_normal, lfan_pivot->f->no);
+
+ if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) {
+ break;
+ }
+ lfan_pivot = lfan_pivot_next;
+ }
+ if (normalize_v3(avg_normal) < CLNORS_VALID_VEC_LEN) {
+ /* If avg normal is nearly 0, set clnor to default value. */
+ zero_v3(avg_normal);
+ }
+ while ((l = BLI_SMALLSTACK_POP(loops))) {
+ const int l_index = BM_elem_index_get(l);
+ short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset);
+ BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], avg_normal, clnors);
+ }
+ }
+ }
+ } while ((l_curr = l_curr->next) != l_first);
+ }
+}
+
+static int normals_split_merge(bContext *C, const bool do_merge)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMEdge *e;
+ BMIter eiter;
+
+ BKE_editmesh_lnorspace_update(em);
+
+ BMLoopNorEditDataArray *lnors_ed_arr = do_merge ? BM_loop_normal_editdata_array_init(bm) : NULL;
+
+ mesh_set_smooth_faces(em, do_merge);
+
+ BM_ITER_MESH(e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_set(e, BM_ELEM_SMOOTH, do_merge);
+ }
+ }
+ if (do_merge == 0) {
+ Mesh *me = obedit->data;
+ me->drawflag |= ME_DRAWSHARP;
+ }
+
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+ BKE_editmesh_lnorspace_update(em);
+
+ if (do_merge) {
+ normals_merge(bm, lnors_ed_arr);
+ }
+ else {
+ normals_split(bm);
+ }
+
+ if (lnors_ed_arr) {
+ BM_loop_normal_editdata_array_free(lnors_ed_arr);
+ }
+
+ EDBM_update_generic(em, true, false);
+
+ return OPERATOR_FINISHED;
+}
+
+static int edbm_merge_normals_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ return normals_split_merge(C, true);
+}
+
+void MESH_OT_merge_normals(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Merge Normals";
+ ot->description = "Merge custom normals of selected vertices";
+ ot->idname = "MESH_OT_merge_normals";
+
+ /* api callbacks */
+ ot->exec = edbm_merge_normals_exec;
+ ot->poll = ED_operator_editmesh_auto_smooth;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int edbm_split_normals_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ return normals_split_merge(C, false);
+}
+
+void MESH_OT_split_normals(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Split Normals";
+ ot->description = "Split custom normals of selected vertices";
+ ot->idname = "MESH_OT_split_normals";
+
+ /* api callbacks */
+ ot->exec = edbm_split_normals_exec;
+ ot->poll = ED_operator_editmesh_auto_smooth;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/********************** Average Loop Normals **********************/
+
+enum {
+ EDBM_CLNOR_AVERAGE_LOOP = 1,
+ EDBM_CLNOR_AVERAGE_FACE_AREA = 2,
+ EDBM_CLNOR_AVERAGE_ANGLE = 3,
+};
+
+static EnumPropertyItem average_method_items[] = {
+ {EDBM_CLNOR_AVERAGE_LOOP, "CUSTOM_NORMAL", 0, "Custom Normal", "Take Average of vert Normals"},
+ {EDBM_CLNOR_AVERAGE_FACE_AREA, "FACE_AREA", 0, "Face Area", "Set all vert normals by Face Area"},
+ {EDBM_CLNOR_AVERAGE_ANGLE, "CORNER_ANGLE", 0, "Corner Angle", "Set all vert normals by Corner Angle"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static int edbm_average_normals_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMFace *f;
+ BMLoop *l, *l_curr, *l_first;
+ BMIter fiter;
+
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+ BKE_editmesh_lnorspace_update(em);
+
+ const int average_type = RNA_enum_get(op->ptr, "average_type");
+ const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+ const float absweight = (float) RNA_int_get(op->ptr, "weight");
+ const float threshold = RNA_float_get(op->ptr, "threshold");
+
+ float weight = absweight / 50.0f;
+ if (absweight == 100.0f) {
+ weight = (float)SHRT_MAX;
+ }
+ else if (absweight == 1.0f) {
+ weight = 1 / (float)SHRT_MAX;
+ }
+ else if ((weight - 1) * 25 > 1) {
+ weight = (weight - 1) * 25;
+ }
+
+ BM_normals_loops_edges_tag(bm, true);
+
+ Heap *loop_weight = BLI_heap_new();
+
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ l_curr = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_curr->v, BM_ELEM_SELECT) && (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) ||
+ (!BM_elem_flag_test(l_curr, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_curr))))
+ {
+ if (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) && !BM_elem_flag_test(l_curr->prev->e, BM_ELEM_TAG)) {
+ const int loop_index = BM_elem_index_get(l_curr);
+ short *clnors = BM_ELEM_CD_GET_VOID_P(l_curr, cd_clnors_offset);
+ BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], f->no, clnors);
+ }
+ else {
+ BMVert *v_pivot = l_curr->v;
+ BMEdge *e_next;
+ const BMEdge *e_org = l_curr->e;
+ BMLoop *lfan_pivot, *lfan_pivot_next;
+
+ lfan_pivot = l_curr;
+ e_next = lfan_pivot->e;
+
+ while (true) {
+ lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next);
+ if (lfan_pivot_next) {
+ BLI_assert(lfan_pivot_next->v == v_pivot);
+ }
+ else {
+ e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e;
+ }
+
+ float val = 1.0f;
+ if (average_type == EDBM_CLNOR_AVERAGE_FACE_AREA) {
+ val = 1.0f / BM_face_calc_area(lfan_pivot->f);
+ }
+ else if (average_type == EDBM_CLNOR_AVERAGE_ANGLE) {
+ val = 1.0f / BM_loop_calc_face_angle(lfan_pivot);
+ }
+
+ BLI_heap_insert(loop_weight, val, lfan_pivot);
+
+ if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) {
+ break;
+ }
+ lfan_pivot = lfan_pivot_next;
+ }
+
+ BLI_SMALLSTACK_DECLARE(loops, BMLoop *);
+ float wnor[3], avg_normal[3] = { 0.0f }, count = 0;
+ float val = BLI_heap_node_value(BLI_heap_top(loop_weight));
+
+ while (!BLI_heap_is_empty(loop_weight)) {
+ const float cur_val = BLI_heap_node_value(BLI_heap_top(loop_weight));
+ if (!compare_ff(val, cur_val, threshold)) {
+ count++;
+ val = cur_val;
+ }
+ l = BLI_heap_pop_min(loop_weight);
+ BLI_SMALLSTACK_PUSH(loops, l);
+
+ const float n_weight = pow(weight, count);
+
+ if (average_type == EDBM_CLNOR_AVERAGE_LOOP) {
+ const int l_index = BM_elem_index_get(l);
+ short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset);
+ BKE_lnor_space_custom_data_to_normal(bm->lnor_spacearr->lspacearr[l_index], clnors, wnor);
+ }
+ else {
+ copy_v3_v3(wnor, l->f->no);
+ }
+ mul_v3_fl(wnor, (1.0f / cur_val) * (1.0f / n_weight));
+ add_v3_v3(avg_normal, wnor);
+ }
+
+ if (normalize_v3(avg_normal) < CLNORS_VALID_VEC_LEN) {
+ /* If avg normal is nearly 0, set clnor to default value. */
+ zero_v3(avg_normal);
+ }
+ while ((l = BLI_SMALLSTACK_POP(loops))) {
+ const int l_index = BM_elem_index_get(l);
+ short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset);
+ BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], avg_normal, clnors);
+ }
+ }
+ }
+ } while ((l_curr = l_curr->next) != l_first);
+ }
+
+ BLI_heap_free(loop_weight, NULL);
+ EDBM_update_generic(em, true, false);
+
+ return OPERATOR_FINISHED;
+}
+
+static bool average_normals_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data))
+{
+ const char *prop_id = RNA_property_identifier(prop);
+ const int average_type = RNA_enum_get(ptr, "average_type");
+
+ /* Only show weight/threshold options in loop average type. */
+ if (STREQ(prop_id, "weight")) {
+ return (average_type == EDBM_CLNOR_AVERAGE_LOOP);
+ }
+ else if (STREQ(prop_id, "threshold")) {
+ return (average_type == EDBM_CLNOR_AVERAGE_LOOP);
+ }
+
+ /* Else, show it! */
+ return true;
+}
+
+static void edbm_average_normals_ui(bContext *C, wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ PointerRNA ptr;
+
+ RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+
+ /* Main auto-draw call */
+ uiDefAutoButsRNA(layout, &ptr, average_normals_draw_check_prop, NULL, '\0', false);
+}
+
+void MESH_OT_average_normals(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Average Normals";
+ ot->description = "Average custom normals of selected vertices";
+ ot->idname = "MESH_OT_average_normals";
+
+ /* api callbacks */
+ ot->exec = edbm_average_normals_exec;
+ ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->ui = edbm_average_normals_ui;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_enum(ot->srna, "average_type", average_method_items, EDBM_CLNOR_AVERAGE_LOOP,
+ "Type", "Averaging method");
+ RNA_def_property_flag(ot->prop, PROP_HIDDEN);
+
+ RNA_def_int(ot->srna, "weight", 50, 1, 100, "Weight", "Weight applied per face", 1, 100);
+
+ RNA_def_float(ot->srna, "threshold", 0.01f, 0, 10, "Threshold",
+ "Threshold value for different weights to be considered equal", 0, 5);
+}
+
+/********************** Custom Normal Interface Tools **********************/
+
+enum {
+ EDBM_CLNOR_TOOLS_COPY = 1,
+ EDBM_CLNOR_TOOLS_PASTE = 2,
+ EDBM_CLNOR_TOOLS_MULTIPLY = 3,
+ EDBM_CLNOR_TOOLS_ADD = 4,
+ EDBM_CLNOR_TOOLS_RESET = 5,
+};
+
+static EnumPropertyItem normal_vector_tool_items[] = {
+ {EDBM_CLNOR_TOOLS_COPY, "COPY", 0, "Copy Normal", "Copy normal to buffer"},
+ {EDBM_CLNOR_TOOLS_PASTE, "PASTE", 0, "Paste Normal", "Paste normal from buffer"},
+ {EDBM_CLNOR_TOOLS_ADD, "ADD", 0, "Add Normal", "Add normal vector with selection"},
+ {EDBM_CLNOR_TOOLS_MULTIPLY, "MULTIPLY", 0, "Multiply Normal", "Multiply normal vector with selection"},
+ {EDBM_CLNOR_TOOLS_RESET, "RESET", 0, "Reset Normal", "Reset buffer and/or normal of selected element"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static int edbm_normals_tools_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+
+ const int mode = RNA_enum_get(op->ptr, "mode");
+ const bool absolute = RNA_boolean_get(op->ptr, "absolute");
+
+ BKE_editmesh_lnorspace_update(em);
+ BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
+ BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
+
+ float *normal_vector = scene->toolsettings->normal_vector;
+
+ switch (mode) {
+ case EDBM_CLNOR_TOOLS_COPY:
+ if (bm->totfacesel != 1 && lnors_ed_arr->totloop != 1 && bm->totvertsel != 1) {
+ BKE_report(op->reports, RPT_ERROR, "Can only copy custom normal, vertex normal or face normal");
+ BM_loop_normal_editdata_array_free(lnors_ed_arr);
+ return OPERATOR_CANCELLED;
+ }
+ bool join = true;
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
+ if (!compare_v3v3(lnors_ed_arr->lnor_editdata->nloc, lnor_ed->nloc, 1e-4f)) {
+ join = false;
+ }
+ }
+ if (lnors_ed_arr->totloop == 1) {
+ copy_v3_v3(scene->toolsettings->normal_vector, lnors_ed_arr->lnor_editdata->nloc);
+ }
+ else if (bm->totfacesel == 1) {
+ BMFace *f;
+ BMIter fiter;
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ copy_v3_v3(scene->toolsettings->normal_vector, f->no);
+ }
+ }
+ }
+ else if (join) {
+ copy_v3_v3(scene->toolsettings->normal_vector, lnors_ed_arr->lnor_editdata->nloc);
+ }
+ break;
+
+ case EDBM_CLNOR_TOOLS_PASTE:
+ if (!absolute) {
+ if (normalize_v3(normal_vector) < CLNORS_VALID_VEC_LEN) {
+ /* If normal is nearly 0, do nothing. */
+ break;
+ }
+ }
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
+ if (absolute) {
+ float abs_normal[3];
+ copy_v3_v3(abs_normal, lnor_ed->loc);
+ negate_v3(abs_normal);
+ add_v3_v3(abs_normal, normal_vector);
+
+ if (normalize_v3(abs_normal) < CLNORS_VALID_VEC_LEN) {
+ /* If abs normal is nearly 0, set clnor to initial value. */
+ copy_v3_v3(abs_normal, lnor_ed->niloc);
+ }
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], abs_normal, lnor_ed->clnors_data);
+ }
+ else {
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], normal_vector, lnor_ed->clnors_data);
+ }
+ }
+ break;
+
+ case EDBM_CLNOR_TOOLS_MULTIPLY:
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
+ mul_v3_v3(lnor_ed->nloc, normal_vector);
+
+ if (normalize_v3(lnor_ed->nloc) < CLNORS_VALID_VEC_LEN) {
+ /* If abs normal is nearly 0, set clnor to initial value. */
+ copy_v3_v3(lnor_ed->nloc, lnor_ed->niloc);
+ }
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data);
+ }
+ break;
+
+ case EDBM_CLNOR_TOOLS_ADD:
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
+ add_v3_v3(lnor_ed->nloc, normal_vector);
+
+ if (normalize_v3(lnor_ed->nloc) < CLNORS_VALID_VEC_LEN) {
+ /* If abs normal is nearly 0, set clnor to initial value. */
+ copy_v3_v3(lnor_ed->nloc, lnor_ed->niloc);
+ }
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data);
+ }
+ break;
+
+ case EDBM_CLNOR_TOOLS_RESET:
+ zero_v3(normal_vector);
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], normal_vector, lnor_ed->clnors_data);
+ }
+ break;
+
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ BM_loop_normal_editdata_array_free(lnors_ed_arr);
+
+ EDBM_update_generic(em, true, false);
+ return OPERATOR_FINISHED;
+}
+
+static bool normals_tools_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data))
+{
+ const char *prop_id = RNA_property_identifier(prop);
+ const int mode = RNA_enum_get(ptr, "mode");
+
+ /* Only show absolute option in paste mode. */
+ if (STREQ(prop_id, "absolute")) {
+ return (mode == EDBM_CLNOR_TOOLS_PASTE);
+ }
+
+ /* Else, show it! */
+ return true;
+}
+
+static void edbm_normals_tools_ui(bContext *C, wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ PointerRNA ptr;
+
+ RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+
+ /* Main auto-draw call */
+ uiDefAutoButsRNA(layout, &ptr, normals_tools_draw_check_prop, NULL, '\0', false);
+}
+
+void MESH_OT_normals_tools(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Normals Vector Tools";
+ ot->description = "Custom normals tools using Normal Vector of UI";
+ ot->idname = "MESH_OT_normals_tools";
+
+ /* api callbacks */
+ ot->exec = edbm_normals_tools_exec;
+ ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->ui = edbm_normals_tools_ui;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_enum(ot->srna, "mode", normal_vector_tool_items, EDBM_CLNOR_TOOLS_COPY,
+ "Mode", "Mode of tools taking input from Interface");
+ RNA_def_property_flag(ot->prop, PROP_HIDDEN);
+
+ RNA_def_boolean(ot->srna, "absolute", false, "Absolute Coordinates", "Copy Absolute coordinates or Normal vector");
+}
+
+static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op)
+{
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMFace *f;
+ BMVert *v;
+ BMEdge *e;
+ BMLoop *l;
+ BMIter fiter, viter, eiter, liter;
+
+ const bool keep_sharp = RNA_boolean_get(op->ptr, "keep_sharp");
+
+ BKE_editmesh_lnorspace_update(em);
+
+ float(*vnors)[3] = MEM_callocN(sizeof(*vnors) * bm->totvert, __func__);
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_ITER_ELEM(v, &viter, f, BM_VERTS_OF_FACE) {
+ const int v_index = BM_elem_index_get(v);
+ add_v3_v3(vnors[v_index], f->no);
+ }
+ }
+ }
+ for (int i = 0; i < bm->totvert; i++) {
+ if (!is_zero_v3(vnors[i]) && normalize_v3(vnors[i]) < CLNORS_VALID_VEC_LEN) {
+ zero_v3(vnors[i]);
+ }
+ }
+
+ BLI_bitmap *loop_set = BLI_BITMAP_NEW(bm->totloop, __func__);
+ const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM(e, &eiter, f, BM_EDGES_OF_FACE) {
+ if (!keep_sharp || (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && BM_elem_flag_test(e, BM_ELEM_SELECT))) {
+ BM_ITER_ELEM(v, &viter, e, BM_VERTS_OF_EDGE) {
+ l = BM_face_vert_share_loop(f, v);
+ const int l_index = BM_elem_index_get(l);
+ const int v_index = BM_elem_index_get(l->v);
+
+ if (!is_zero_v3(vnors[v_index])) {
+ short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset);
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[l_index], vnors[v_index], clnors);
+
+ if (bm->lnor_spacearr->lspacearr[l_index]->flags & MLNOR_SPACE_IS_SINGLE) {
+ BLI_BITMAP_ENABLE(loop_set, l_index);
+ }
+ else {
+ LinkNode *loops = bm->lnor_spacearr->lspacearr[l_index]->loops;
+ for (; loops; loops = loops->next) {
+ BLI_BITMAP_ENABLE(loop_set, BM_elem_index_get((BMLoop *)loops->link));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ int v_index;
+ BM_ITER_MESH_INDEX(v, &viter, bm, BM_VERTS_OF_MESH, v_index) {
+ BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
+ if (BLI_BITMAP_TEST(loop_set, BM_elem_index_get(l))) {
+ const int loop_index = BM_elem_index_get(l);
+ short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset);
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[loop_index], vnors[v_index], clnors);
+ }
+ }
+ }
+
+ MEM_freeN(loop_set);
+ MEM_freeN(vnors);
+ EDBM_update_generic(em, true, false);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_set_normals_from_faces(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Set Normals From Faces";
+ ot->description = "Set the custom normals from the selected faces ones";
+ ot->idname = "MESH_OT_set_normals_from_faces";
+
+ /* api callbacks */
+ ot->exec = edbm_set_normals_from_faces_exec;
+ ot->poll = ED_operator_editmesh_auto_smooth;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "keep_sharp", 0, "Keep Sharp Edges", "Do not set sharp edges to face");
+}
+
+static int edbm_smoothen_normals_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMFace *f;
+ BMLoop *l;
+ BMIter fiter, liter;
+
+ BKE_editmesh_lnorspace_update(em);
+ BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
+
+ float(*smooth_normal)[3] = MEM_callocN(sizeof(*smooth_normal) * lnors_ed_arr->totloop, __func__);
+
+ /* This is weird choice of operation, taking all loops of faces of current vertex... Could lead to some rather
+ * far away loops weighting as much as very close ones (topologically speaking), with complex polygons.
+ * Using topological distance here (rather than geometrical one) makes sense imho, but would rather go with
+ * a more consistent and flexible code, we could even add max topological distance to take into account,
+ * and a weighting curve...
+ * Would do that later though, think for now we can live with that choice. --mont29 */
+ BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
+ l = lnor_ed->loop;
+ float loop_normal[3];
+
+ BM_ITER_ELEM(f, &fiter, l->v, BM_FACES_OF_VERT) {
+ BMLoop *l_other;
+ BM_ITER_ELEM(l_other, &liter, f, BM_LOOPS_OF_FACE) {
+ const int l_index_other = BM_elem_index_get(l_other);
+ short *clnors = BM_ELEM_CD_GET_VOID_P(l_other, lnors_ed_arr->cd_custom_normal_offset);
+ BKE_lnor_space_custom_data_to_normal(bm->lnor_spacearr->lspacearr[l_index_other], clnors, loop_normal);
+ add_v3_v3(smooth_normal[i], loop_normal);
+ }
+ }
+ }
+
+ const float factor = RNA_float_get(op->ptr, "factor");
+
+ lnor_ed = lnors_ed_arr->lnor_editdata;
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
+ float current_normal[3];
+
+ if (normalize_v3(smooth_normal[i]) < CLNORS_VALID_VEC_LEN) {
+ /* Skip in case smoothen normal is invalid... */
+ continue;
+ }
+
+ BKE_lnor_space_custom_data_to_normal(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->clnors_data, current_normal);
+
+ /* Note: again, this is not true spherical interpolation that normals would need...
+ * But it's probably good enough for now. */
+ mul_v3_fl(current_normal, 1.0f - factor);
+ mul_v3_fl(smooth_normal[i], factor);
+ add_v3_v3(current_normal, smooth_normal[i]);
+
+ if (normalize_v3(current_normal) < CLNORS_VALID_VEC_LEN) {
+ /* Skip in case smoothen normal is invalid... */
+ continue;
+ }
+
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], current_normal, lnor_ed->clnors_data);
+ }
+
+ BM_loop_normal_editdata_array_free(lnors_ed_arr);
+ MEM_freeN(smooth_normal);
+
+ EDBM_update_generic(em, true, false);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_smoothen_normals(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Smoothen Normals";
+ ot->description = "Smoothen custom normals based on adjacent vertex normals";
+ ot->idname = "MESH_OT_smoothen_normals";
+
+ /* api callbacks */
+ ot->exec = edbm_smoothen_normals_exec;
+ ot->poll = ED_operator_editmesh_auto_smooth;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_float(ot->srna, "factor", 0.5f, 0.0f, 1.0f, "Factor",
+ "Specifies weight of smooth vs original normal", 0.0f, 1.0f);
+}
+
+/********************** Weighted Normal Modifier Face Strength **********************/
+
+static int edbm_mod_weighted_strength_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMFace *f;
+ BMIter fiter;
+
+ BM_select_history_clear(bm);
+
+ const char *layer_id = MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID;
+ int cd_prop_int_index = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_INT, layer_id);
+ if (cd_prop_int_index == -1) {
+ BM_data_layer_add_named(bm, &bm->pdata, CD_PROP_INT, layer_id);
+ cd_prop_int_index = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_INT, layer_id);
+ }
+ cd_prop_int_index -= CustomData_get_layer_index(&bm->pdata, CD_PROP_INT);
+ const int cd_prop_int_offset = CustomData_get_n_offset(&bm->pdata, CD_PROP_INT, cd_prop_int_index);
+
+ const int face_strength = scene->toolsettings->face_strength;
+ const bool set = RNA_boolean_get(op->ptr, "set");
+ BM_mesh_elem_index_ensure(bm, BM_FACE);
+
+ if (set) {
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ int *strength = BM_ELEM_CD_GET_VOID_P(f, cd_prop_int_offset);
+ *strength = face_strength;
+ }
+ }
+ }
+ else {
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ int *strength = BM_ELEM_CD_GET_VOID_P(f, cd_prop_int_offset);
+ if (*strength == face_strength) {
+ BM_face_select_set(bm, f, true);
+ BM_select_history_store(bm, f);
+ }
+ else {
+ BM_face_select_set(bm, f, false);
+ }
+ }
+ }
+
+ EDBM_update_generic(em, false, false);
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Face Strength";
+ ot->description = "Set/Get strength of face (used in Weighted Normal modifier)";
+ ot->idname = "MESH_OT_mod_weighted_strength";
+
+ /* api callbacks */
+ ot->exec = edbm_mod_weighted_strength_exec;
+ ot->poll = ED_operator_editmesh_auto_smooth;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_boolean(ot->srna, "set", 0, "Set value", "Set Value of faces");
+ RNA_def_property_flag(ot->prop, PROP_HIDDEN);
+}
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 11606840b42..26f3c17a97c 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -598,6 +598,8 @@ static void undomesh_to_editmesh(UndoMesh *um, BMEditMesh *em, Mesh *obmesh)
bm->selectmode = um->selectmode;
em->ob = ob;
+ bm->spacearr_dirty = BM_SPACEARR_DIRTY_ALL;
+
/* T35170: Restore the active key on the RealMesh. Otherwise 'fake' offset propagation happens
* if the active is a basis for any other. */
if (key && (key->type == KEY_RELATIVE)) {
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 2ee3362063b..fd87ba32653 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -565,8 +565,8 @@ UvVertMap *BM_uv_vert_map_create(
}
BM_ITER_ELEM_INDEX(l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- buf->tfindex = i;
- buf->f = a;
+ buf->loop_of_poly_index = i;
+ buf->poly_index = a;
buf->separate = 0;
buf->next = vmap->vert[BM_elem_index_get(l->v)];
@@ -597,9 +597,9 @@ UvVertMap *BM_uv_vert_map_create(
v->next = newvlist;
newvlist = v;
- efa = BM_face_at_index(bm, v->f);
+ efa = BM_face_at_index(bm, v->poly_index);
- l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, v->tfindex);
+ l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, v->loop_of_poly_index);
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv = luv->uv;
@@ -608,15 +608,15 @@ UvVertMap *BM_uv_vert_map_create(
while (iterv) {
next = iterv->next;
- efa = BM_face_at_index(bm, iterv->f);
- l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex);
+ efa = BM_face_at_index(bm, iterv->poly_index);
+ l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, iterv->loop_of_poly_index);
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv2 = luv->uv;
sub_v2_v2v2(uvdiff, uv2, uv);
if (fabsf(uvdiff[0]) < limit[0] && fabsf(uvdiff[1]) < limit[1] &&
- (!use_winding || winding[iterv->f] == winding[v->f]))
+ (!use_winding || winding[iterv->poly_index] == winding[v->poly_index]))
{
if (lastv) lastv->next = next;
else vlist = next;
@@ -713,7 +713,7 @@ UvElementMap *BM_uv_element_map_create(
buf->l = l;
buf->separate = 0;
buf->island = INVALID_ISLAND;
- buf->tfindex = i;
+ buf->loop_of_poly_index = i;
buf->next = element_map->vert[BM_elem_index_get(l->v)];
element_map->vert[BM_elem_index_get(l->v)] = buf;
@@ -826,7 +826,7 @@ UvElementMap *BM_uv_element_map_create(
map[element - element_map->buf] = islandbufsize;
islandbuf[islandbufsize].l = element->l;
islandbuf[islandbufsize].separate = element->separate;
- islandbuf[islandbufsize].tfindex = element->tfindex;
+ islandbuf[islandbufsize].loop_of_poly_index = element->loop_of_poly_index;
islandbuf[islandbufsize].island = nislands;
islandbufsize++;
@@ -1348,7 +1348,10 @@ void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_d
/* in debug mode double check we didn't need to recalculate */
BLI_assert(BM_mesh_elem_table_check(em->bm) == true);
}
-
+ if (em->bm->spacearr_dirty & BM_SPACEARR_BMO_SET) {
+ BM_lnorspace_invalidate(em->bm, false);
+ em->bm->spacearr_dirty &= ~BM_SPACEARR_BMO_SET;
+ }
/* don't keep stale derivedMesh data around, see: [#38872] */
BKE_editmesh_free_derivedmesh(em);
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index cc9448e5e06..4a67dea9d4b 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -240,6 +240,16 @@ void MESH_OT_duplicate(struct wmOperatorType *ot);
void MESH_OT_merge(struct wmOperatorType *ot);
void MESH_OT_remove_doubles(struct wmOperatorType *ot);
void MESH_OT_poke(struct wmOperatorType *ot);
+void MESH_OT_point_normals(struct wmOperatorType *ot);
+void MESH_OT_merge_normals(struct wmOperatorType *ot);
+void MESH_OT_split_normals(struct wmOperatorType *ot);
+void MESH_OT_normals_tools(struct wmOperatorType *ot);
+void MESH_OT_set_normals_from_faces(struct wmOperatorType *ot);
+void MESH_OT_average_normals(struct wmOperatorType *ot);
+void MESH_OT_smoothen_normals(struct wmOperatorType *ot);
+void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot);
+
+struct wmKeyMap *point_normals_modal_keymap(wmKeyConfig *keyconf);
#ifdef WITH_FREESTYLE
void MESH_OT_mark_freestyle_edge(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 0fcc5ada854..842a1ecab35 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -200,6 +200,15 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_bisect);
WM_operatortype_append(MESH_OT_symmetrize);
WM_operatortype_append(MESH_OT_symmetry_snap);
+
+ WM_operatortype_append(MESH_OT_point_normals);
+ WM_operatortype_append(MESH_OT_merge_normals);
+ WM_operatortype_append(MESH_OT_split_normals);
+ WM_operatortype_append(MESH_OT_normals_tools);
+ WM_operatortype_append(MESH_OT_set_normals_from_faces);
+ WM_operatortype_append(MESH_OT_average_normals);
+ WM_operatortype_append(MESH_OT_smoothen_normals);
+ WM_operatortype_append(MESH_OT_mod_weighted_strength);
}
#if 0 /* UNUSED, remove? */
@@ -335,22 +344,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "MESH_OT_bevel", BKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "vertex_only", true);
- /* selecting */
- for (int i = 0; i < 4; i++) {
- const bool is_extend = (i & 1);
- const bool is_expand = (i & 2);
- const int key_modifier = (is_extend ? KM_SHIFT : 0) | (is_expand ? KM_CTRL : 0);
- for (int j = 0; j < 3; j++) {
- kmi = WM_keymap_add_item(keymap, "MESH_OT_select_mode", ONEKEY + j, KM_PRESS, key_modifier, 0);
- RNA_enum_set(kmi->ptr, "type", SCE_SELECT_VERTEX << j);
- if (is_extend) {
- RNA_boolean_set(kmi->ptr, "use_extend", true);
- }
- if (is_expand) {
- RNA_boolean_set(kmi->ptr, "use_expand", true);
- }
- }
- }
+ /* Selec Vert/Edge/Face. */
+ ED_keymap_editmesh_elem_mode(keyconf, keymap);
/* standard mouse selection goes via space_view3d */
kmi = WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
@@ -479,6 +474,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MESH_OT_split", YKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_vert_connect_path", JKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_point_normals", LKEY, KM_PRESS, KM_ALT, 0);
+
/* Vertex Slide */
WM_keymap_add_item(keymap, "TRANSFORM_OT_vert_slide", VKEY, KM_PRESS, KM_SHIFT, 0);
/* use KM_CLICK because same key is used for tweaks */
@@ -528,4 +525,5 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
ED_keymap_proportional_editmode(keyconf, keymap, true);
knifetool_modal_keymap(keyconf);
+ point_normals_modal_keymap(keyconf);
}
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index 305e3287029..739975a6278 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -31,6 +31,8 @@ set(INC
../../makesdna
../../makesrna
../../modifiers
+ ../../gpencil_modifiers
+ ../../shader_fx
../../python
../../render/extern/include
../../windowmanager
@@ -53,6 +55,8 @@ set(SRC
object_hook.c
object_modes.c
object_modifier.c
+ object_gpencil_modifier.c
+ object_shader_fx.c
object_ops.c
object_random.c
object_relations.c
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index a8917f4c4aa..f41c4071634 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -71,6 +71,7 @@
#include "BKE_displist.h"
#include "BKE_effect.h"
#include "BKE_font.h"
+#include "BKE_gpencil.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
#include "BKE_layer.h"
@@ -103,6 +104,7 @@
#include "ED_armature.h"
#include "ED_curve.h"
+#include "ED_gpencil.h"
#include "ED_mball.h"
#include "ED_mesh.h"
#include "ED_node.h"
@@ -985,6 +987,119 @@ void OBJECT_OT_drop_named_image(wmOperatorType *ot)
ED_object_add_generic_props(ot, false);
}
+/********************* Add Gpencil Operator ********************/
+
+static int object_gpencil_add_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = (ob && (ob->type == OB_GPENCIL)) ? ob->data : NULL;
+
+ const int type = RNA_enum_get(op->ptr, "type");
+
+ float loc[3], rot[3];
+ unsigned int layer;
+ bool newob = false;
+
+ /* Hack: Force view-align to be on by default
+ * since it's not nice for adding shapes in 2D
+ * for them to end up aligned oddly, but only for Monkey
+ */
+ if ((RNA_struct_property_is_set(op->ptr, "view_align") == false) &&
+ (type == GP_MONKEY))
+ {
+ RNA_boolean_set(op->ptr, "view_align", true);
+ }
+
+ /* Note: We use 'Y' here (not 'Z'), as */
+ WM_operator_view3d_unit_defaults(C, op);
+ if (!ED_object_add_generic_get_opts(C, op, 'Y', loc, rot, NULL, &layer, NULL))
+ return OPERATOR_CANCELLED;
+
+ /* add new object if not currently editing a GP object,
+ * or if "empty" was chosen (i.e. user wants a blank GP canvas)
+ */
+ if ((gpd == NULL) || (GPENCIL_ANY_MODE(gpd) == false) || (type == GP_EMPTY)) {
+ const char *ob_name = (type == GP_MONKEY) ? "Suzanne" : NULL;
+ float radius = RNA_float_get(op->ptr, "radius");
+
+ ob = ED_object_add_type(C, OB_GPENCIL, ob_name, loc, rot, true, layer);
+ gpd = ob->data;
+ newob = true;
+
+ BKE_object_obdata_size_init(ob, GP_OBGPENCIL_DEFAULT_SIZE * radius);
+ }
+ else {
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_ADDED, NULL);
+ }
+
+ /* create relevant geometry */
+ switch (type) {
+ case GP_STROKE:
+ {
+ float radius = RNA_float_get(op->ptr, "radius");
+ float mat[4][4];
+
+ ED_object_new_primitive_matrix(C, ob, loc, rot, mat);
+ mul_v3_fl(mat[0], radius);
+ mul_v3_fl(mat[1], radius);
+ mul_v3_fl(mat[2], radius);
+
+ ED_gpencil_create_stroke(C, mat);
+ break;
+ }
+ case GP_MONKEY:
+ {
+ float radius = RNA_float_get(op->ptr, "radius");
+ float mat[4][4];
+
+ ED_object_new_primitive_matrix(C, ob, loc, rot, mat);
+ mul_v3_fl(mat[0], radius);
+ mul_v3_fl(mat[1], radius);
+ mul_v3_fl(mat[2], radius);
+
+ ED_gpencil_create_monkey(C, mat);
+ break;
+ }
+ case GP_EMPTY:
+ /* do nothing */
+ break;
+
+ default:
+ BKE_report(op->reports, RPT_WARNING, "Not implemented");
+ break;
+ }
+
+ /* if this is a new object, initialise default stuff (colors, etc.) */
+ if (newob) {
+ ED_gpencil_add_defaults(C);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_gpencil_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add GPencil";
+ ot->description = "Add a grease pencil object to the scene";
+ ot->idname = "OBJECT_OT_gpencil_add";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = object_gpencil_add_exec;
+ ot->poll = ED_operator_scene_editable;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ED_object_add_unit_props(ot);
+ ED_object_add_generic_props(ot, false);
+
+ ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_object_gpencil_type_items, 0, "Type", "");
+}
+
/********************* Add Light Operator ********************/
static const char *get_light_defname(int type)
@@ -1479,7 +1594,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
ob_dst->parent = NULL;
BKE_constraints_free(&ob_dst->constraints);
- ob_dst->curve_cache = NULL;
+ ob_dst->runtime.curve_cache = NULL;
ob_dst->transflag &= ~OB_DUPLI;
copy_m4_m4(ob_dst->obmat, dob->mat);
@@ -1638,7 +1753,7 @@ static const EnumPropertyItem convert_target_items[] = {
static void convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
- if (ob->curve_cache == NULL) {
+ if (ob->runtime.curve_cache == NULL) {
/* Force creation. This is normally not needed but on operator
* redo we might end up with an object which isn't evaluated yet.
*/
@@ -1781,6 +1896,10 @@ static int convert_exec(bContext *C, wmOperator *op)
if (ob->type == OB_MESH) {
BKE_object_free_modifiers(ob, 0); /* after derivedmesh calls! */
}
+ if (ob->type == OB_GPENCIL) {
+ BKE_object_free_modifiers(ob, 0); /* after derivedmesh calls! */
+ BKE_object_free_shaderfx(ob, 0);
+ }
}
}
else if (ob->type == OB_MESH && target == OB_CURVE) {
@@ -1966,7 +2085,7 @@ static int convert_exec(bContext *C, wmOperator *op)
}
convert_ensure_curve_cache(depsgraph, scene, baseob);
- BKE_mesh_from_metaball(&baseob->curve_cache->disp, newob->data);
+ BKE_mesh_from_metaball(&baseob->runtime.curve_cache->disp, newob->data);
if (obact->type == OB_MBALL) {
basact = basen;
@@ -2122,6 +2241,10 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer
ID_NEW_REMAP_US(obn->mat[a])
else {
obn->mat[a] = ID_NEW_SET(obn->mat[a], BKE_material_copy(bmain, obn->mat[a]));
+ /* duplicate grease pencil settings */
+ if (ob->mat[a]->gp_style) {
+ obn->mat[a]->gp_style = MEM_dupallocN(ob->mat[a]->gp_style);
+ }
}
id_us_min(id);
@@ -2222,7 +2345,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer
ID_NEW_REMAP_US2(obn->data)
else {
obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data));
- BKE_pose_rebuild(obn, obn->data);
+ BKE_pose_rebuild(bmain, obn, obn->data, true);
didit = 1;
}
id_us_min(id);
@@ -2258,6 +2381,16 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer
id_us_min(id);
}
break;
+ case OB_GPENCIL:
+ if (dupflag != 0) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_gpencil_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
}
/* check if obdata is copied */
@@ -2482,7 +2615,7 @@ static bool join_poll(bContext *C)
if (!ob || ID_IS_LINKED(ob)) return 0;
- if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE))
+ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE, OB_GPENCIL))
return ED_operator_screenactive(C);
else
return 0;
@@ -2500,6 +2633,13 @@ static int join_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Cannot edit external libdata");
return OPERATOR_CANCELLED;
}
+ else if (ob->type == OB_GPENCIL) {
+ bGPdata *gpd = (bGPdata *)ob->data;
+ if ((!gpd) || GPENCIL_ANY_MODE(gpd)) {
+ BKE_report(op->reports, RPT_ERROR, "This data does not support joining in this mode");
+ return OPERATOR_CANCELLED;
+ }
+ }
if (ob->type == OB_MESH)
return join_mesh_exec(C, op);
@@ -2507,6 +2647,8 @@ static int join_exec(bContext *C, wmOperator *op)
return join_curve_exec(C, op);
else if (ob->type == OB_ARMATURE)
return join_armature_exec(C, op);
+ else if (ob->type == OB_GPENCIL)
+ return ED_gpencil_join_objects_exec(C, op);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 5210182510f..e8fabdabf17 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -49,6 +49,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_image.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_material.h"
@@ -357,17 +358,24 @@ static bool is_noncolor_pass(eScenePassType pass_type)
}
/* if all is good tag image and return true */
-static bool bake_object_check(Scene *scene, Object *ob, ReportList *reports)
+static bool bake_object_check(ViewLayer *view_layer, Object *ob, ReportList *reports)
{
Image *image;
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
void *lock;
int i;
- if ((ob->lay & scene->lay) == 0) {
- BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not on a scene layer", ob->id.name + 2);
+ if (base == NULL) {
+ BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not in view layer", ob->id.name + 2);
return false;
}
+ if (!(base->flag & BASE_ENABLED_RENDER)) {
+ BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not enabled for rendering", ob->id.name + 2);
+ return false;
+ }
+
+
if (ob->type != OB_MESH) {
BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", ob->id.name + 2);
return false;
@@ -497,7 +505,7 @@ static bool bake_pass_filter_check(eScenePassType pass_type, const int pass_filt
}
/* before even getting in the bake function we check for some basic errors */
-static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase *selected_objects,
+static bool bake_objects_check(Main *bmain, ViewLayer *view_layer, Object *ob, ListBase *selected_objects,
ReportList *reports, const bool is_selected_to_active)
{
CollectionPointerLink *link;
@@ -508,7 +516,7 @@ static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase *
if (is_selected_to_active) {
int tot_objects = 0;
- if (!bake_object_check(scene, ob, reports))
+ if (!bake_object_check(view_layer, ob, reports))
return false;
for (link = selected_objects->first; link; link = link->next) {
@@ -536,7 +544,7 @@ static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase *
}
for (link = selected_objects->first; link; link = link->next) {
- if (!bake_object_check(scene, link->ptr.data, reports))
+ if (!bake_object_check(view_layer, link->ptr.data, reports))
return false;
}
}
@@ -1204,7 +1212,7 @@ static int bake_exec(bContext *C, wmOperator *op)
goto finally;
}
- if (!bake_objects_check(bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) {
+ if (!bake_objects_check(bkr.main, bkr.view_layer, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) {
goto finally;
}
@@ -1263,7 +1271,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa
return;
}
- if (!bake_objects_check(bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) {
+ if (!bake_objects_check(bkr->main, bkr->view_layer, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) {
bkr->result = OPERATOR_CANCELLED;
return;
}
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index f56fd560946..ad0b091ede9 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -450,8 +450,9 @@ static bool data_transfer_poll(bContext *C)
}
/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
-static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+static bool data_transfer_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
{
+ PointerRNA *ptr = op->ptr;
PropertyRNA *prop_other;
const char *prop_id = RNA_property_identifier(prop);
@@ -512,19 +513,6 @@ static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
return true;
}
-/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
-static void data_transfer_ui(bContext *C, wmOperator *op)
-{
- uiLayout *layout = op->layout;
- wmWindowManager *wm = CTX_wm_manager(C);
- PointerRNA ptr;
-
- RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-
- /* Main auto-draw call */
- uiDefAutoButsRNA(layout, &ptr, data_transfer_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
-}
-
/* transfers weight from active to selected */
void OBJECT_OT_data_transfer(wmOperatorType *ot)
{
@@ -537,10 +525,10 @@ void OBJECT_OT_data_transfer(wmOperatorType *ot)
/* API callbacks.*/
ot->poll = data_transfer_poll;
+ ot->poll_property = data_transfer_poll_property;
ot->invoke = WM_menu_invoke;
ot->exec = data_transfer_exec;
ot->check = data_transfer_check;
- ot->ui = data_transfer_ui;
/* Flags.*/
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -700,10 +688,10 @@ void OBJECT_OT_datalayout_transfer(wmOperatorType *ot)
ot->idname = "OBJECT_OT_datalayout_transfer";
ot->poll = datalayout_transfer_poll;
+ ot->poll_property = data_transfer_poll_property;
ot->invoke = datalayout_transfer_invoke;
ot->exec = datalayout_transfer_exec;
ot->check = data_transfer_check;
- ot->ui = data_transfer_ui;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index a6c3c86922d..a6dad906579 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -100,6 +100,7 @@
#include "ED_screen.h"
#include "ED_undo.h"
#include "ED_image.h"
+#include "ED_gpencil.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -1377,6 +1378,9 @@ static void object_clear_mpath(Object *ob)
animviz_free_motionpath(ob->mpath);
ob->mpath = NULL;
ob->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS;
+
+ /* tag object for copy on write - so removed paths don't still show */
+ DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
}
}
@@ -1539,7 +1543,6 @@ static const EnumPropertyItem *object_mode_set_itemsf(
const EnumPropertyItem *input = rna_enum_object_mode_items;
EnumPropertyItem *item = NULL;
Object *ob;
- bGPdata *gpd;
int totitem = 0;
if (!C) /* needed for docs */
@@ -1555,7 +1558,9 @@ static const EnumPropertyItem *object_mode_set_itemsf(
(input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) ||
(input->value == OB_MODE_PARTICLE_EDIT && use_mode_particle_edit) ||
(ELEM(input->value, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT,
- OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) ||
+ OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) ||
+ (ELEM(input->value, OB_MODE_GPENCIL_EDIT, OB_MODE_GPENCIL_PAINT,
+ OB_MODE_GPENCIL_SCULPT, OB_MODE_GPENCIL_WEIGHT) && (ob->type == OB_GPENCIL)) ||
(input->value == OB_MODE_OBJECT))
{
RNA_enum_item_add(&item, &totitem, input);
@@ -1568,14 +1573,6 @@ static const EnumPropertyItem *object_mode_set_itemsf(
RNA_enum_items_add_value(&item, &totitem, input, OB_MODE_OBJECT);
}
- /* On top of all the rest, GPencil Stroke Edit Mode
- * is available if there's a valid gp datablock...
- */
- gpd = CTX_data_gpencil_data(C);
- if (gpd) {
- RNA_enum_items_add_value(&item, &totitem, rna_enum_object_mode_items, OB_MODE_GPENCIL);
- }
-
RNA_enum_item_end(&item, &totitem);
*r_free = true;
@@ -1600,7 +1597,6 @@ static int object_mode_set_exec(bContext *C, wmOperator *op)
{
bool use_submode = STREQ(op->idname, "OBJECT_OT_mode_set_or_submode");
Object *ob = CTX_data_active_object(C);
- bGPdata *gpd = CTX_data_gpencil_data(C);
eObjectMode mode = RNA_enum_get(op->ptr, "mode");
eObjectMode restore_mode = (ob) ? ob->mode : OB_MODE_OBJECT;
const bool toggle = RNA_boolean_get(op->ptr, "toggle");
@@ -1620,22 +1616,9 @@ static int object_mode_set_exec(bContext *C, wmOperator *op)
}
}
- if (gpd) {
- /* GP Mode is not bound to a specific object. Therefore,
- * we don't want it to be actually saved on any objects,
- * as weirdness can happen if you select other objects,
- * or load old files.
- *
- * Instead, we use the following 2 rules to ensure that
- * the mode selector works as expected:
- * 1) If there's no object, we want to enter editmode.
- * (i.e. with no object, we're in object mode)
- * 2) Otherwise, exit stroke editmode, so that we can
- * enter another mode...
- */
- if (!ob || (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
- WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_EXEC_REGION_WIN, NULL);
- }
+ /* by default the operator assume is a mesh, but if gp object change mode */
+ if ((ob != NULL) && (ob->type == OB_GPENCIL) && (mode == OB_MODE_EDIT)) {
+ mode = OB_MODE_GPENCIL_EDIT;
}
if (!ob || !ED_object_mode_compat_test(ob, mode))
@@ -1666,6 +1649,14 @@ static int object_mode_set_exec(bContext *C, wmOperator *op)
}
}
+ /* if type is OB_GPENCIL, set cursor mode */
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ if (ob->data) {
+ bGPdata *gpd = (bGPdata *)ob->data;
+ ED_gpencil_setup_modes(C, gpd, ob->mode);
+ }
+ }
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c
new file mode 100644
index 00000000000..175fb1706fb
--- /dev/null
+++ b/source/blender/editors/object/object_gpencil_modifier.c
@@ -0,0 +1,637 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2018 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation, 2018
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/object/object_gpencil_modifier.c
+ * \ingroup edobj
+ */
+
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_gpencil_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BLI_math.h"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_string_utf8.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+#include "BKE_main.h"
+#include "BKE_gpencil_modifier.h"
+#include "BKE_report.h"
+#include "BKE_object.h"
+#include "BKE_gpencil.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "ED_object.h"
+#include "ED_screen.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "object_intern.h"
+
+/******************************** API ****************************/
+
+GpencilModifierData *ED_object_gpencil_modifier_add(
+ ReportList *reports, Main *bmain, Scene *UNUSED(scene), Object *ob, const char *name, int type)
+{
+ GpencilModifierData *new_md = NULL;
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(type);
+
+ if (ob->type != OB_GPENCIL) {
+ BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2);
+ return NULL;
+ }
+
+ if (mti->flags & eGpencilModifierTypeFlag_Single) {
+ if (BKE_gpencil_modifiers_findByType(ob, type)) {
+ BKE_report(reports, RPT_WARNING, "Only one modifier of this type is allowed");
+ return NULL;
+ }
+ }
+
+ /* get new modifier data to add */
+ new_md = BKE_gpencil_modifier_new(type);
+
+ BLI_addtail(&ob->greasepencil_modifiers, new_md);
+
+ if (name) {
+ BLI_strncpy_utf8(new_md->name, name, sizeof(new_md->name));
+ }
+
+ /* make sure modifier data has unique name */
+ BKE_gpencil_modifier_unique_name(&ob->greasepencil_modifiers, new_md);
+
+
+ bGPdata *gpd = ob->data;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_relations_tag_update(bmain);
+
+ 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,
+ bool *UNUSED(r_sort_depsgraph))
+{
+ /* It seems on rapid delete it is possible to
+ * get called twice on same modifier, so make
+ * sure it is in list. */
+ if (BLI_findindex(&ob->greasepencil_modifiers, md) == -1) {
+ return 0;
+ }
+
+ DEG_relations_tag_update(bmain);
+
+ BLI_remlink(&ob->greasepencil_modifiers, md);
+ BKE_gpencil_modifier_free(md);
+ BKE_object_free_derived_caches(ob);
+
+ return 1;
+}
+
+bool ED_object_gpencil_modifier_remove(ReportList *reports, Main *bmain, Object *ob, GpencilModifierData *md)
+{
+ bool sort_depsgraph = false;
+ bool ok;
+
+ ok = gpencil_object_modifier_remove(bmain, ob, md, &sort_depsgraph);
+
+ if (!ok) {
+ BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", md->name, ob->id.name);
+ return 0;
+ }
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_relations_tag_update(bmain);
+
+ return 1;
+}
+
+void ED_object_gpencil_modifier_clear(Main *bmain, Object *ob)
+{
+ GpencilModifierData *md = ob->greasepencil_modifiers.first;
+ bool sort_depsgraph = false;
+
+ if (!md)
+ return;
+
+ while (md) {
+ GpencilModifierData *next_md;
+
+ next_md = md->next;
+
+ gpencil_object_modifier_remove(bmain, ob, md, &sort_depsgraph);
+
+ md = next_md;
+ }
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_relations_tag_update(bmain);
+}
+
+int ED_object_gpencil_modifier_move_up(ReportList *UNUSED(reports), Object *ob, GpencilModifierData *md)
+{
+ if (md->prev) {
+ BLI_remlink(&ob->greasepencil_modifiers, md);
+ BLI_insertlinkbefore(&ob->greasepencil_modifiers, md->prev, md);
+ }
+
+ return 1;
+}
+
+int ED_object_gpencil_modifier_move_down(ReportList *UNUSED(reports), Object *ob, GpencilModifierData *md)
+{
+ if (md->next) {
+ BLI_remlink(&ob->greasepencil_modifiers, md);
+ BLI_insertlinkafter(&ob->greasepencil_modifiers, md->next, md);
+ }
+
+ return 1;
+}
+
+static int gpencil_modifier_apply_obdata(
+ ReportList *reports, Main *bmain, Depsgraph *depsgraph, Object *ob, GpencilModifierData *md)
+{
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
+
+ if (mti->isDisabled && mti->isDisabled(md, 0)) {
+ BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
+ return 0;
+ }
+
+ if (ob->type == OB_GPENCIL) {
+ if (ELEM(NULL, ob, ob->data)) {
+ return 0;
+ }
+ else if (mti->bakeModifier == NULL) {
+ BKE_report(reports, RPT_ERROR, "Not implemented");
+ return 0;
+ }
+ mti->bakeModifier(bmain, depsgraph, md, ob);
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ }
+ else {
+ BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
+ return 0;
+ }
+
+ return 1;
+}
+
+int ED_object_gpencil_modifier_apply(
+ Main *bmain, ReportList *reports, Depsgraph *depsgraph,
+ Object *ob, GpencilModifierData *md, int UNUSED(mode))
+{
+
+ if (ob->type == OB_GPENCIL) {
+ if (ob->mode != OB_MODE_OBJECT) {
+ BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in paint, sculpt or edit mode");
+ return 0;
+ }
+
+ if (((ID *)ob->data)->us > 1) {
+ BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
+ return 0;
+ }
+ }
+ else if (((ID *)ob->data)->us > 1) {
+ BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
+ return 0;
+ }
+
+ if (md != ob->greasepencil_modifiers.first)
+ BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
+
+ if (!gpencil_modifier_apply_obdata(reports, bmain, depsgraph, ob, md)) {
+ return 0;
+ }
+
+ BLI_remlink(&ob->greasepencil_modifiers, md);
+ BKE_gpencil_modifier_free(md);
+
+ return 1;
+}
+
+int ED_object_gpencil_modifier_copy(ReportList *UNUSED(reports), Object *ob, GpencilModifierData *md)
+{
+ GpencilModifierData *nmd;
+
+ nmd = BKE_gpencil_modifier_new(md->type);
+ BKE_gpencil_modifier_copyData(md, nmd);
+ BLI_insertlinkafter(&ob->greasepencil_modifiers, md, nmd);
+ BKE_gpencil_modifier_unique_name(&ob->greasepencil_modifiers, nmd);
+
+ return 1;
+}
+
+/************************ add modifier operator *********************/
+
+static int gpencil_modifier_add_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = ED_object_active_context(C);
+ int type = RNA_enum_get(op->ptr, "type");
+
+ if (!ED_object_gpencil_modifier_add(op->reports, bmain, scene, ob, NULL, type))
+ return OPERATOR_CANCELLED;
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static const EnumPropertyItem *gpencil_modifier_add_itemf(
+ bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ Object *ob = ED_object_active_context(C);
+ EnumPropertyItem *item = NULL;
+ const EnumPropertyItem *md_item, *group_item = NULL;
+ const GpencilModifierTypeInfo *mti;
+ int totitem = 0, a;
+
+ if (!ob)
+ return rna_enum_object_greasepencil_modifier_type_items;
+
+ for (a = 0; rna_enum_object_greasepencil_modifier_type_items[a].identifier; a++) {
+ md_item = &rna_enum_object_greasepencil_modifier_type_items[a];
+ if (md_item->identifier[0]) {
+ mti = BKE_gpencil_modifierType_getInfo(md_item->value);
+
+ if (mti->flags & eGpencilModifierTypeFlag_NoUserAdd)
+ continue;
+ }
+ else {
+ group_item = md_item;
+ md_item = NULL;
+
+ continue;
+ }
+
+ if (group_item) {
+ RNA_enum_item_add(&item, &totitem, group_item);
+ group_item = NULL;
+ }
+
+ RNA_enum_item_add(&item, &totitem, md_item);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+void OBJECT_OT_gpencil_modifier_add(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Add Grease Pencil Modifier";
+ ot->description = "Add a procedural operation/effect to the active grease pencil object";
+ ot->idname = "OBJECT_OT_gpencil_modifier_add";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = gpencil_modifier_add_exec;
+ ot->poll = ED_operator_object_active_editable;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_enum(ot->srna, "type", rna_enum_object_modifier_type_items, eGpencilModifierType_Thick, "Type", "");
+ RNA_def_enum_funcs(prop, gpencil_modifier_add_itemf);
+ ot->prop = prop;
+}
+
+/************************ generic functions for operators using mod names and data context *********************/
+
+static int gpencil_edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
+{
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
+ Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);
+
+ if (!ptr.data) {
+ CTX_wm_operator_poll_msg_set(C, "Context missing 'modifier'");
+ return 0;
+ }
+
+ if (!ob || ID_IS_LINKED(ob)) return 0;
+ if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) return 0;
+ if (ptr.id.data && ID_IS_LINKED(ptr.id.data)) return 0;
+
+ if (ID_IS_STATIC_OVERRIDE(ob)) {
+ CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers comming from static override");
+ return (((GpencilModifierData *)ptr.data)->flag & eGpencilModifierFlag_StaticOverride_Local) != 0;
+ }
+
+ return 1;
+}
+
+static bool gpencil_edit_modifier_poll(bContext *C)
+{
+ return gpencil_edit_modifier_poll_generic(C, &RNA_GpencilModifier, 0);
+}
+
+static void gpencil_edit_modifier_properties(wmOperatorType *ot)
+{
+ RNA_def_string(ot->srna, "modifier", NULL, MAX_NAME, "Modifier", "Name of the modifier to edit");
+}
+
+static int gpencil_edit_modifier_invoke_properties(bContext *C, wmOperator *op)
+{
+ GpencilModifierData *md;
+
+ 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;
+ }
+ }
+
+ return false;
+}
+
+static GpencilModifierData *gpencil_edit_modifier_property_get(wmOperator *op, Object *ob, int type)
+{
+ char modifier_name[MAX_NAME];
+ GpencilModifierData *md;
+ RNA_string_get(op->ptr, "modifier", modifier_name);
+
+ md = BKE_gpencil_modifiers_findByName(ob, modifier_name);
+
+ if (md && type != 0 && md->type != type)
+ md = NULL;
+
+ return md;
+}
+
+/************************ remove modifier operator *********************/
+
+static int gpencil_modifier_remove_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ 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))
+ return OPERATOR_CANCELLED;
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int gpencil_modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (gpencil_edit_modifier_invoke_properties(C, op))
+ return gpencil_modifier_remove_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_gpencil_modifier_remove(wmOperatorType *ot)
+{
+ ot->name = "Remove Grease Pencil Modifier";
+ ot->description = "Remove a modifier from the active grease pencil object";
+ ot->idname = "OBJECT_OT_gpencil_modifier_remove";
+
+ ot->invoke = gpencil_modifier_remove_invoke;
+ ot->exec = gpencil_modifier_remove_exec;
+ ot->poll = gpencil_edit_modifier_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ gpencil_edit_modifier_properties(ot);
+}
+
+/************************ move up modifier operator *********************/
+
+static int gpencil_modifier_move_up_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_move_up(op->reports, ob, md))
+ return OPERATOR_CANCELLED;
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int gpencil_modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (gpencil_edit_modifier_invoke_properties(C, op))
+ return gpencil_modifier_move_up_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_gpencil_modifier_move_up(wmOperatorType *ot)
+{
+ ot->name = "Move Up Modifier";
+ ot->description = "Move modifier up in the stack";
+ ot->idname = "OBJECT_OT_gpencil_modifier_move_up";
+
+ ot->invoke = gpencil_modifier_move_up_invoke;
+ ot->exec = gpencil_modifier_move_up_exec;
+ ot->poll = gpencil_edit_modifier_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ gpencil_edit_modifier_properties(ot);
+}
+
+/************************ move down modifier operator *********************/
+
+static int gpencil_modifier_move_down_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_move_down(op->reports, ob, md))
+ return OPERATOR_CANCELLED;
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int gpencil_modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (gpencil_edit_modifier_invoke_properties(C, op))
+ return gpencil_modifier_move_down_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_gpencil_modifier_move_down(wmOperatorType *ot)
+{
+ ot->name = "Move Down Modifier";
+ ot->description = "Move modifier down in the stack";
+ ot->idname = "OBJECT_OT_gpencil_modifier_move_down";
+
+ ot->invoke = gpencil_modifier_move_down_invoke;
+ ot->exec = gpencil_modifier_move_down_exec;
+ ot->poll = gpencil_edit_modifier_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ gpencil_edit_modifier_properties(ot);
+}
+
+/************************ apply modifier operator *********************/
+
+static int gpencil_modifier_apply_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Object *ob = ED_object_active_context(C);
+ 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)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int gpencil_modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (gpencil_edit_modifier_invoke_properties(C, op))
+ return gpencil_modifier_apply_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+static const EnumPropertyItem gpencil_modifier_apply_as_items[] = {
+ {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
+ {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+void OBJECT_OT_gpencil_modifier_apply(wmOperatorType *ot)
+{
+ ot->name = "Apply Modifier";
+ ot->description = "Apply modifier and remove from the stack";
+ ot->idname = "OBJECT_OT_gpencil_modifier_apply";
+
+ ot->invoke = gpencil_modifier_apply_invoke;
+ ot->exec = gpencil_modifier_apply_exec;
+ ot->poll = gpencil_edit_modifier_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+
+ RNA_def_enum(ot->srna, "apply_as", gpencil_modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
+ gpencil_edit_modifier_properties(ot);
+}
+
+/************************ copy modifier operator *********************/
+
+static int gpencil_modifier_copy_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_copy(op->reports, ob, md))
+ return OPERATOR_CANCELLED;
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int gpencil_modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (gpencil_edit_modifier_invoke_properties(C, op))
+ return gpencil_modifier_copy_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_gpencil_modifier_copy(wmOperatorType *ot)
+{
+ ot->name = "Copy Modifier";
+ ot->description = "Duplicate modifier at the same position in the stack";
+ ot->idname = "OBJECT_OT_gpencil_modifier_copy";
+
+ ot->invoke = gpencil_modifier_copy_invoke;
+ ot->exec = gpencil_modifier_copy_exec;
+ ot->poll = gpencil_edit_modifier_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ gpencil_edit_modifier_properties(ot);
+}
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 53cabe3759e..72c5fde2955 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -411,6 +411,9 @@ static int collection_add_exec(bContext *C, wmOperator *UNUSED(op))
id_fake_user_set(&collection->id);
BKE_collection_object_add(bmain, collection, ob);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
@@ -460,6 +463,9 @@ static int collection_link_exec(bContext *C, wmOperator *op)
BKE_collection_object_add(bmain, collection, ob);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
@@ -500,6 +506,9 @@ static int collection_remove_exec(bContext *C, wmOperator *UNUSED(op))
BKE_collection_object_remove(bmain, collection, ob, false);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
@@ -531,6 +540,8 @@ static int collection_unlink_exec(bContext *C, wmOperator *UNUSED(op))
BKE_libblock_delete(bmain, collection);
+ DEG_relations_tag_update(bmain);
+
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 0e49f8a7790..2cc8671d84b 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -115,6 +115,7 @@ void OBJECT_OT_armature_add(struct wmOperatorType *ot);
void OBJECT_OT_empty_add(struct wmOperatorType *ot);
void OBJECT_OT_lightprobe_add(struct wmOperatorType *ot);
void OBJECT_OT_drop_named_image(struct wmOperatorType *ot);
+void OBJECT_OT_gpencil_add(struct wmOperatorType *ot);
void OBJECT_OT_light_add(struct wmOperatorType *ot);
void OBJECT_OT_effector_add(struct wmOperatorType *ot);
void OBJECT_OT_camera_add(struct wmOperatorType *ot);
@@ -176,6 +177,20 @@ void OBJECT_OT_laplaciandeform_bind(struct wmOperatorType *ot);
void OBJECT_OT_surfacedeform_bind(struct wmOperatorType *ot);
void OBJECT_OT_hair_generate_follicles(struct wmOperatorType *ot);
+/* grease pencil modifiers */
+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_apply(struct wmOperatorType *ot);
+void OBJECT_OT_gpencil_modifier_copy(struct wmOperatorType *ot);
+
+/* shader fx */
+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);
+
/* object_constraint.c */
void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
void OBJECT_OT_constraint_add_with_targets(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c
index e9bd6fbce8f..b9bfb44f680 100644
--- a/source/blender/editors/object/object_modes.c
+++ b/source/blender/editors/object/object_modes.c
@@ -27,6 +27,7 @@
* actual mode switching logic is per-object type.
*/
+#include "DNA_gpencil_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_workspace_types.h"
@@ -71,8 +72,14 @@ static const char *object_mode_op_string(eObjectMode mode)
return "PARTICLE_OT_particle_edit_toggle";
if (mode == OB_MODE_POSE)
return "OBJECT_OT_posemode_toggle";
- if (mode == OB_MODE_GPENCIL)
+ if (mode == OB_MODE_GPENCIL_EDIT)
return "GPENCIL_OT_editmode_toggle";
+ if (mode == OB_MODE_GPENCIL_PAINT)
+ return "GPENCIL_OT_paintmode_toggle";
+ if (mode == OB_MODE_GPENCIL_SCULPT)
+ return "GPENCIL_OT_sculptmode_toggle";
+ if (mode == OB_MODE_GPENCIL_WEIGHT)
+ return "GPENCIL_OT_weightmode_toggle";
return NULL;
}
@@ -85,8 +92,6 @@ bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode)
if (ob) {
if (mode == OB_MODE_OBJECT)
return true;
- else if (mode == OB_MODE_GPENCIL)
- return true; /* XXX: assume this is the case for now... */
switch (ob->type) {
case OB_MESH:
@@ -111,6 +116,13 @@ bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode)
if (mode & (OB_MODE_EDIT | OB_MODE_POSE))
return true;
break;
+ case OB_GPENCIL:
+ if (mode & (OB_MODE_EDIT | OB_MODE_GPENCIL_EDIT | OB_MODE_GPENCIL_PAINT |
+ OB_MODE_GPENCIL_SCULPT | OB_MODE_GPENCIL_WEIGHT))
+ {
+ return true;
+ }
+ break;
}
}
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index f2122f7961a..8384755c679 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -1,31 +1,31 @@
/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * 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) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * Contributor(s): Blender Foundation, 2009
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+* ***** BEGIN GPL LICENSE BLOCK *****
+*
+* 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) 2001-2002 by NaN Holding BV.
+* All rights reserved.
+*
+* Contributor(s): Blender Foundation, 2009
+*
+* ***** END GPL LICENSE BLOCK *****
+*/
/** \file blender/editors/object/object_modifier.c
- * \ingroup edobj
- */
+* \ingroup edobj
+*/
#include <math.h>
@@ -120,8 +120,8 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
if (type == eModifierType_ParticleSystem) {
/* don't need to worry about the new modifier's name, since that is set to the number
- * of particle systems which shouldn't have too many duplicates
- */
+ * of particle systems which shouldn't have too many duplicates
+ */
new_md = object_add_particle_system(bmain, scene, ob, name);
}
else {
@@ -185,9 +185,9 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
}
/* Return true if the object has a modifier of type 'type' other than
- * the modifier pointed to be 'exclude', otherwise returns false. */
+* the modifier pointed to be 'exclude', otherwise returns false. */
static bool object_has_modifier(const Object *ob, const ModifierData *exclude,
- ModifierType type)
+ ModifierType type)
{
ModifierData *md;
@@ -200,16 +200,17 @@ static bool object_has_modifier(const Object *ob, const ModifierData *exclude,
}
/* If the object data of 'orig_ob' has other users, run 'callback' on
- * each of them.
- *
- * If include_orig is true, the callback will run on 'orig_ob' too.
- *
- * If the callback ever returns true, iteration will stop and the
- * function value will be true. Otherwise the function returns false.
- */
-bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig,
- bool (*callback)(Object *ob, void *callback_data),
- void *callback_data)
+* each of them.
+*
+* If include_orig is true, the callback will run on 'orig_ob' too.
+*
+* If the callback ever returns true, iteration will stop and the
+* function value will be true. Otherwise the function returns false.
+*/
+bool ED_object_iter_other(
+ Main *bmain, Object *orig_ob, const bool include_orig,
+ bool (*callback)(Object *ob, void *callback_data),
+ void *callback_data)
{
ID *ob_data_id = orig_ob->data;
int users = ob_data_id->us;
@@ -250,8 +251,8 @@ static bool object_has_modifier_cb(Object *ob, void *data)
}
/* Use with ED_object_iter_other(). Sets the total number of levels
- * for any multires modifiers on the object to the int pointed to by
- * callback_data. */
+* for any multires modifiers on the object to the int pointed to by
+* callback_data. */
bool ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v)
{
ModifierData *md;
@@ -268,20 +269,20 @@ bool ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v)
/* Return true if no modifier of type 'type' other than 'exclude' */
static bool object_modifier_safe_to_delete(Main *bmain, Object *ob,
- ModifierData *exclude,
- ModifierType type)
+ ModifierData *exclude,
+ ModifierType type)
{
return (!object_has_modifier(ob, exclude, type) &&
- !ED_object_iter_other(bmain, ob, false,
- object_has_modifier_cb, &type));
+ !ED_object_iter_other(bmain, ob, false,
+ object_has_modifier_cb, &type));
}
static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md,
- bool *r_sort_depsgraph)
+ bool *r_sort_depsgraph)
{
/* It seems on rapid delete it is possible to
- * get called twice on same modifier, so make
- * sure it is in list. */
+ * get called twice on same modifier, so make
+ * sure it is in list. */
if (BLI_findindex(&ob->modifiers, md) == -1) {
return 0;
}
@@ -525,7 +526,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *
}
static int modifier_apply_shape(
- Main *bmain, ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md)
+ Main *bmain, ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md)
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -535,15 +536,15 @@ static int modifier_apply_shape(
}
/*
- * It should be ridiculously easy to extract the original verts that we want
- * and form the shape data. We can probably use the CD KEYINDEX layer (or
- * whatever I ended up calling it, too tired to check now), though this would
- * by necessity have to make some potentially ugly assumptions about the order
- * of the mesh data :-/ you can probably assume in 99% of cases that the first
- * element of a given index is the original, and any subsequent duplicates are
- * copies/interpolates, but that's an assumption that would need to be tested
- * and then predominantly stated in comments in a half dozen headers.
- */
+ * It should be ridiculously easy to extract the original verts that we want
+ * and form the shape data. We can probably use the CD KEYINDEX layer (or
+ * whatever I ended up calling it, too tired to check now), though this would
+ * by necessity have to make some potentially ugly assumptions about the order
+ * of the mesh data :-/ you can probably assume in 99% of cases that the first
+ * element of a given index is the original, and any subsequent duplicates are
+ * copies/interpolates, but that's an assumption that would need to be tested
+ * and then predominantly stated in comments in a half dozen headers.
+ */
if (ob->type == OB_MESH) {
Mesh *mesh_applied;
@@ -566,7 +567,7 @@ static int modifier_apply_shape(
key = me->key = BKE_key_add(bmain, (ID *)me);
key->type = KEY_RELATIVE;
/* if that was the first key block added, then it was the basis.
- * Initialize it with the mesh, and add another for the modifier */
+ * Initialize it with the mesh, and add another for the modifier */
kb = BKE_keyblock_add(key, NULL);
BKE_keyblock_convert_from_mesh(me, key, kb);
}
@@ -670,8 +671,8 @@ static int modifier_apply_obdata(ReportList *reports, Depsgraph *depsgraph, Scen
}
int ED_object_modifier_apply(
- Main *bmain, ReportList *reports, Depsgraph *depsgraph,
- Scene *scene, Object *ob, ModifierData *md, int mode)
+ Main *bmain, ReportList *reports, Depsgraph *depsgraph,
+ Scene *scene, Object *ob, ModifierData *md, int mode)
{
int prev_mode;
@@ -695,7 +696,7 @@ int ED_object_modifier_apply(
BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
/* Get evaluated modifier, so object links pointer to evaluated data,
- * but still use original object it is applied to the original mesh. */
+ * but still use original object it is applied to the original mesh. */
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
ModifierData *md_eval = (ob_eval) ? modifiers_findByName(ob_eval, md->name) : md;
@@ -755,7 +756,7 @@ static int modifier_add_exec(bContext *C, wmOperator *op)
}
static const EnumPropertyItem *modifier_add_itemf(
- bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+ bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
{
Object *ob = ED_object_active_context(C);
EnumPropertyItem *item = NULL;
@@ -1168,8 +1169,8 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
multiresModifier_del_levels(mmd, scene, ob, 1);
ED_object_iter_other(CTX_data_main(C), ob, true,
- ED_object_multires_update_totlevels_cb,
- &mmd->totlvl);
+ ED_object_multires_update_totlevels_cb,
+ &mmd->totlvl);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
@@ -1213,8 +1214,8 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
multiresModifier_subdivide(mmd, scene, ob, 0, mmd->simple);
ED_object_iter_other(CTX_data_main(C), ob, true,
- ED_object_multires_update_totlevels_cb,
- &mmd->totlvl);
+ ED_object_multires_update_totlevels_cb,
+ &mmd->totlvl);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
@@ -1390,8 +1391,8 @@ void OBJECT_OT_multires_external_save(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
WM_operator_properties_filesel(
- ot, FILE_TYPE_FOLDER | FILE_TYPE_BTX, FILE_SPECIAL, FILE_SAVE,
- WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
+ ot, FILE_TYPE_FOLDER | FILE_TYPE_BTX, FILE_SPECIAL, FILE_SAVE,
+ WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
edit_modifier_properties(ot);
}
@@ -1483,13 +1484,13 @@ static void modifier_skin_customdata_delete(Object *ob)
static bool skin_poll(bContext *C)
{
return (!CTX_data_edit_object(C) &&
- edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
+ edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
}
static bool skin_edit_poll(bContext *C)
{
return (CTX_data_edit_object(C) &&
- edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
+ edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
}
static void skin_root_clear(BMVert *bm_vert, GSet *visited, const int cd_vert_skin_offset)
@@ -1582,8 +1583,8 @@ static int skin_loose_mark_clear_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) {
MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
- bm_vert->head.data,
- CD_MVERT_SKIN);
+ bm_vert->head.data,
+ CD_MVERT_SKIN);
switch (action) {
@@ -1639,8 +1640,8 @@ static int skin_radii_equalize_exec(bContext *C, wmOperator *UNUSED(op))
BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) {
MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
- bm_vert->head.data,
- CD_MVERT_SKIN);
+ bm_vert->head.data,
+ CD_MVERT_SKIN);
float avg = (vs->radius[0] + vs->radius[1]) * 0.5f;
vs->radius[0] = vs->radius[1] = avg;
@@ -1667,12 +1668,12 @@ void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot)
}
static void skin_armature_bone_create(Object *skin_ob,
- MVert *mvert, MEdge *medge,
- bArmature *arm,
- BLI_bitmap *edges_visited,
- const MeshElemMap *emap,
- EditBone *parent_bone,
- int parent_v)
+ MVert *mvert, MEdge *medge,
+ bArmature *arm,
+ BLI_bitmap *edges_visited,
+ const MeshElemMap *emap,
+ EditBone *parent_bone,
+ int parent_v)
{
int i;
@@ -1707,12 +1708,12 @@ static void skin_armature_bone_create(Object *skin_ob,
}
skin_armature_bone_create(skin_ob,
- mvert, medge,
- arm,
- edges_visited,
- emap,
- bone,
- v);
+ mvert, medge,
+ arm,
+ edges_visited,
+ emap,
+ bone,
+ v);
}
}
@@ -1734,10 +1735,10 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
/* add vertex weights to original mesh */
CustomData_add_layer(&me->vdata,
- CD_MDEFORMVERT,
- CD_CALLOC,
- NULL,
- me->totvert);
+ CD_MDEFORMVERT,
+ CD_CALLOC,
+ NULL,
+ me->totvert);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
arm_ob = BKE_object_add(bmain, scene, view_layer, OB_ARMATURE, NULL);
@@ -1750,19 +1751,19 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
mvert_skin = CustomData_get_layer(&me->vdata, CD_MVERT_SKIN);
BKE_mesh_vert_edge_map_create(&emap, &emap_mem,
- me->medge, me->totvert, me->totedge);
+ me->medge, me->totvert, me->totedge);
edges_visited = BLI_BITMAP_NEW(me->totedge, "edge_visited");
/* note: we use EditBones here, easier to set them up and use
- * edit-armature functions to convert back to regular bones */
+ * edit-armature functions to convert back to regular bones */
for (v = 0; v < me->totvert; v++) {
if (mvert_skin[v].flag & MVERT_SKIN_ROOT) {
EditBone *bone = NULL;
/* Unless the skin root has just one adjacent edge, create
- * a fake root bone (have it going off in the Y direction
- * (arbitrary) */
+ * a fake root bone (have it going off in the Y direction
+ * (arbitrary) */
if (emap[v].count > 1) {
bone = ED_armature_ebone_add(arm, "Bone");
@@ -1775,12 +1776,12 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
if (emap[v].count >= 1) {
skin_armature_bone_create(skin_ob,
- mvert, me->medge,
- arm,
- edges_visited,
- emap,
- bone,
- v);
+ mvert, me->medge,
+ arm,
+ edges_visited,
+ emap,
+ bone,
+ v);
}
}
}
@@ -2095,7 +2096,7 @@ static int oceanbake_breakjob(void *UNUSED(customdata))
//return *(ob->stop);
/* this is not nice yet, need to make the jobs list template better
- * for identifying/acting upon various different jobs */
+ * for identifying/acting upon various different jobs */
/* but for now we'll reuse the render break... */
return (G.is_break);
}
@@ -2169,8 +2170,8 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
}
och = BKE_ocean_init_cache(omd->cachepath, modifier_path_relbase(bmain, ob),
- omd->bakestart, omd->bakeend, omd->wave_scale,
- omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution);
+ omd->bakestart, omd->bakeend, omd->wave_scale,
+ omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution);
och->time = MEM_mallocN(och->duration * sizeof(float), "foam bake time");
@@ -2179,22 +2180,22 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
/* precalculate time variable before baking */
for (f = omd->bakestart; f <= omd->bakeend; f++) {
/* from physics_fluid.c:
- *
- * XXX: This can't be used due to an anim sys optimization that ignores recalc object animation,
- * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ )
- * --> BKE_animsys_evaluate_all_animation(bmain, eval_time);
- * This doesn't work with drivers:
- * --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL);
- */
+ *
+ * XXX: This can't be used due to an anim sys optimization that ignores recalc object animation,
+ * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ )
+ * --> BKE_animsys_evaluate_all_animation(bmain, eval_time);
+ * This doesn't work with drivers:
+ * --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL);
+ */
/* Modifying the global scene isn't nice, but we can do it in
- * this part of the process before a threaded job is created */
+ * this part of the process before a threaded job is created */
//scene->r.cfra = f;
//ED_update_for_newframe(bmain, scene);
/* ok, this doesn't work with drivers, but is way faster.
- * let's use this for now and hope nobody wants to drive the time value... */
+ * let's use this for now and hope nobody wants to drive the time value... */
BKE_animsys_evaluate_animdata(CTX_data_depsgraph(C), scene, (ID *)ob, ob->adt, f, ADT_RECALC_ANIM);
och->time[i] = omd->time;
@@ -2223,7 +2224,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
/* setup job */
wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Ocean Simulation",
- WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_SIM_OCEAN);
+ WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_SIM_OCEAN);
oj = MEM_callocN(sizeof(OceanBakeJob), "ocean bake job");
oj->owner = ob;
oj->ocean = ocean;
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 192df257bba..16ea0791adf 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -40,6 +40,7 @@
#include "BKE_context.h"
#include "RNA_access.h"
+#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -114,6 +115,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_empty_add);
WM_operatortype_append(OBJECT_OT_lightprobe_add);
WM_operatortype_append(OBJECT_OT_drop_named_image);
+ WM_operatortype_append(OBJECT_OT_gpencil_add);
WM_operatortype_append(OBJECT_OT_light_add);
WM_operatortype_append(OBJECT_OT_camera_add);
WM_operatortype_append(OBJECT_OT_speaker_add);
@@ -146,6 +148,20 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_skin_radii_equalize);
WM_operatortype_append(OBJECT_OT_skin_armature_create);
+ /* grease pencil modifiers */
+ WM_operatortype_append(OBJECT_OT_gpencil_modifier_add);
+ 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_apply);
+ WM_operatortype_append(OBJECT_OT_gpencil_modifier_copy);
+
+ /* shader fx */
+ WM_operatortype_append(OBJECT_OT_shaderfx_add);
+ 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_correctivesmooth_bind);
WM_operatortype_append(OBJECT_OT_meshdeform_bind);
WM_operatortype_append(OBJECT_OT_explode_refresh);
@@ -491,3 +507,26 @@ void ED_keymap_proportional_editmode(struct wmKeyConfig *UNUSED(keyconf), struct
RNA_string_set(kmi->ptr, "value_2", "CONNECTED");
}
}
+
+/**
+ * Map 1..3 to Vert/Edge/Face.
+ */
+void ED_keymap_editmesh_elem_mode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap)
+{
+ for (int i = 0; i < 4; i++) {
+ const bool is_extend = (i & 1);
+ const bool is_expand = (i & 2);
+ const int key_modifier = (is_extend ? KM_SHIFT : 0) | (is_expand ? KM_CTRL : 0);
+ for (int j = 0; j < 3; j++) {
+ wmKeyMapItem *kmi = WM_keymap_add_item(
+ keymap, "MESH_OT_select_mode", ONEKEY + j, KM_PRESS, key_modifier, 0);
+ RNA_enum_set(kmi->ptr, "type", SCE_SELECT_VERTEX << j);
+ if (is_extend) {
+ RNA_boolean_set(kmi->ptr, "use_extend", true);
+ }
+ if (is_expand) {
+ RNA_boolean_set(kmi->ptr, "use_expand", true);
+ }
+ }
+ }
+}
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 324b6eca34a..78e44e52299 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -70,6 +70,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_displist.h"
#include "BKE_global.h"
+#include "BKE_gpencil.h"
#include "BKE_fcurve.h"
#include "BKE_idprop.h"
#include "BKE_lamp.h"
@@ -360,7 +361,7 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
newob = BKE_object_add_from(bmain, scene, view_layer, OB_EMPTY, name, gob ? gob : ob);
/* set layers OK */
- BKE_object_make_proxy(newob, ob, gob);
+ BKE_object_make_proxy(bmain, newob, ob, gob);
/* Set back pointer immediately so dependency graph knows that this is
* is a proxy and will act accordingly. Otherwise correctness of graph
@@ -716,7 +717,7 @@ bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene,
if (md) {
((CurveModifierData *)md)->object = par;
}
- if (par->curve_cache && par->curve_cache->path == NULL) {
+ if (par->runtime.curve_cache && par->runtime.curve_cache->path == NULL) {
DEG_id_tag_update(&par->id, OB_RECALC_DATA);
}
}
@@ -947,13 +948,13 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
return OPERATOR_INTERFACE;
}
-static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+static bool parent_set_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
{
const char *prop_id = RNA_property_identifier(prop);
- const int type = RNA_enum_get(ptr, "type");
/* Only show XMirror for PAR_ARMATURE_ENVELOPE and PAR_ARMATURE_AUTO! */
if (STREQ(prop_id, "xmirror")) {
+ const int type = RNA_enum_get(op->ptr, "type");
if (ELEM(type, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO))
return true;
else
@@ -963,18 +964,6 @@ static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
return true;
}
-static void parent_set_ui(bContext *C, wmOperator *op)
-{
- uiLayout *layout = op->layout;
- wmWindowManager *wm = CTX_wm_manager(C);
- PointerRNA ptr;
-
- RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-
- /* Main auto-draw call. */
- uiDefAutoButsRNA(layout, &ptr, parent_set_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
-}
-
void OBJECT_OT_parent_set(wmOperatorType *ot)
{
/* identifiers */
@@ -986,7 +975,7 @@ void OBJECT_OT_parent_set(wmOperatorType *ot)
ot->invoke = parent_set_invoke;
ot->exec = parent_set_exec;
ot->poll = ED_operator_object_active;
- ot->ui = parent_set_ui;
+ ot->poll_property = parent_set_poll_property;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1621,21 +1610,11 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
/**************************** Make Single User ********************************/
-static Object *single_object_users_object(Main *bmain, Scene *scene, Object *ob)
+static Object *single_object_users_object(Main *bmain, Object *ob)
{
/* base gets copy of object */
Object *obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
- /* remap gpencil parenting */
-
- if (scene->gpd) {
- bGPdata *gpd = scene->gpd;
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- if (gpl->parent == ob) {
- gpl->parent = obn;
- }
- }
- }
id_us_plus(&obn->id);
id_us_min(&ob->id);
@@ -1660,7 +1639,7 @@ static void single_object_users_collection(Main *bmain, Scene *scene, Collection
/* an object may be in more than one collection */
if ((ob->id.newid == NULL) && ((ob->flag & flag) == flag)) {
if (!ID_IS_LINKED(ob) && ob->id.us > 1) {
- cob->ob = single_object_users_object(bmain, scene, cob->ob);
+ cob->ob = single_object_users_object(bmain, cob->ob);
}
}
}
@@ -1714,6 +1693,7 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
/* collection pointers in scene */
BKE_scene_groups_relink(scene);
+ /* active camera */
ID_NEW_REMAP(scene->camera);
if (v3d) ID_NEW_REMAP(v3d->camera);
@@ -1809,7 +1789,7 @@ static void single_obdata_users(Main *bmain, Scene *scene, ViewLayer *view_layer
case OB_ARMATURE:
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
ob->data = ID_NEW_SET(ob->data, BKE_armature_copy(bmain, ob->data));
- BKE_pose_rebuild(ob, ob->data);
+ BKE_pose_rebuild(bmain, ob, ob->data, true);
break;
case OB_SPEAKER:
ob->data = ID_NEW_SET(ob->data, BKE_speaker_copy(bmain, ob->data));
@@ -1817,6 +1797,9 @@ static void single_obdata_users(Main *bmain, Scene *scene, ViewLayer *view_layer
case OB_LIGHTPROBE:
ob->data = ID_NEW_SET(ob->data, BKE_lightprobe_copy(bmain, ob->data));
break;
+ case OB_GPENCIL:
+ ob->data = ID_NEW_SET(ob->data, BKE_gpencil_copy(bmain, ob->data));
+ break;
default:
printf("ERROR %s: can't copy %s\n", __func__, id->name);
BLI_assert(!"This should never happen.");
@@ -1892,6 +1875,7 @@ static void single_mat_users_expand(Main *bmain)
Mesh *me;
Curve *cu;
MetaBall *mb;
+ bGPdata *gpd;
for (ob = bmain->object.first; ob; ob = ob->id.next)
if (ob->id.tag & LIB_TAG_NEW)
@@ -1908,6 +1892,10 @@ static void single_mat_users_expand(Main *bmain)
for (mb = bmain->mball.first; mb; mb = mb->id.next)
if (mb->id.tag & LIB_TAG_NEW)
new_id_matar(bmain, mb->mat, mb->totcol);
+
+ for (gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next)
+ if (gpd->id.tag & LIB_TAG_NEW)
+ new_id_matar(bmain, gpd->mat, gpd->totcol);
}
/* used for copying scenes */
@@ -1952,10 +1940,6 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo
}
}
- if (scene->gpd) {
- IDP_RelinkProperty(scene->gpd->id.properties);
- }
-
if (scene->world) {
IDP_RelinkProperty(scene->world->id.properties);
}
@@ -2329,6 +2313,7 @@ static int make_override_static_exec(bContext *C, wmOperator *op)
if (new_ob != NULL && new_ob->id.override_static != 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, DEG_TAG_TRANSFORM | DEG_TAG_BASE_FLAGS_UPDATE);
}
/* parent to 'collection' empty */
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index d5f7a93cc6e..c23a1d64ee8 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -41,6 +41,7 @@
#include "DNA_armature_types.h"
#include "DNA_lamp_types.h"
#include "DNA_workspace_types.h"
+#include "DNA_gpencil_types.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
@@ -88,8 +89,8 @@
* this takes into account the 'restrict selection in 3d view' flag.
* deselect works always, the restriction just prevents selection */
-/* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! (or
- * or a NC_SCENE|ND_OB_VISIBLE in case of visibility toggling */
+ /* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! (or
+ * or a NC_SCENE|ND_OB_VISIBLE in case of visibility toggling */
void ED_object_base_select(Base *base, eObjectSelect_Mode mode)
{
diff --git a/source/blender/editors/object/object_shader_fx.c b/source/blender/editors/object/object_shader_fx.c
new file mode 100644
index 00000000000..681851850a5
--- /dev/null
+++ b/source/blender/editors/object/object_shader_fx.c
@@ -0,0 +1,469 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2018 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation, 2018
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/object/object_shader_fx.c
+ * \ingroup edobj
+ */
+
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_shader_fx_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BLI_math.h"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_string_utf8.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+#include "BKE_main.h"
+#include "BKE_shader_fx.h"
+#include "BKE_report.h"
+#include "BKE_object.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "ED_object.h"
+#include "ED_screen.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "object_intern.h"
+
+/******************************** API ****************************/
+
+ShaderFxData *ED_object_shaderfx_add(ReportList *reports, Main *bmain, Scene *UNUSED(scene), Object *ob, const char *name, int type)
+{
+ ShaderFxData *new_fx = NULL;
+ const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(type);
+
+ if (ob->type != OB_GPENCIL) {
+ BKE_reportf(reports, RPT_WARNING, "Effect cannot be added to object '%s'", ob->id.name + 2);
+ return NULL;
+ }
+
+ if (fxi->flags & eShaderFxTypeFlag_Single) {
+ if (BKE_shaderfx_findByType(ob, type)) {
+ BKE_report(reports, RPT_WARNING, "Only one Effect of this type is allowed");
+ return NULL;
+ }
+ }
+
+ /* get new effect data to add */
+ new_fx = BKE_shaderfx_new(type);
+
+ BLI_addtail(&ob->shader_fx, new_fx);
+
+ if (name) {
+ BLI_strncpy_utf8(new_fx->name, name, sizeof(new_fx->name));
+ }
+
+ /* make sure effect data has unique name */
+ BKE_shaderfx_unique_name(&ob->shader_fx, new_fx);
+
+ bGPdata *gpd = ob->data;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_relations_tag_update(bmain);
+
+ return new_fx;
+}
+
+/* Return true if the object has a effect of type 'type' other than
+ * the shaderfx pointed to be 'exclude', otherwise returns false. */
+static bool UNUSED_FUNCTION(object_has_shaderfx)(
+ const Object *ob, const ShaderFxData *exclude,
+ ShaderFxType type)
+{
+ ShaderFxData *fx;
+
+ for (fx = ob->shader_fx.first; fx; fx = fx->next) {
+ if ((fx != exclude) && (fx->type == type))
+ return true;
+ }
+
+ return false;
+}
+
+static bool object_shaderfx_remove(
+ Main *bmain, Object *ob, ShaderFxData *fx,
+ bool *UNUSED(r_sort_depsgraph))
+{
+ /* It seems on rapid delete it is possible to
+ * get called twice on same effect, so make
+ * sure it is in list. */
+ if (BLI_findindex(&ob->shader_fx, fx) == -1) {
+ return 0;
+ }
+
+ DEG_relations_tag_update(bmain);
+
+ BLI_remlink(&ob->shader_fx, fx);
+ BKE_shaderfx_free(fx);
+ BKE_object_free_derived_caches(ob);
+
+ return 1;
+}
+
+bool ED_object_shaderfx_remove(ReportList *reports, Main *bmain, Object *ob, ShaderFxData *fx)
+{
+ bool sort_depsgraph = false;
+ bool ok;
+
+ ok = object_shaderfx_remove(bmain, ob, fx, &sort_depsgraph);
+
+ if (!ok) {
+ BKE_reportf(reports, RPT_ERROR, "Effect '%s' not in object '%s'", fx->name, ob->id.name);
+ return 0;
+ }
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_relations_tag_update(bmain);
+
+ return 1;
+}
+
+void ED_object_shaderfx_clear(Main *bmain, Object *ob)
+{
+ ShaderFxData *fx = ob->shader_fx.first;
+ bool sort_depsgraph = false;
+
+ if (!fx)
+ return;
+
+ while (fx) {
+ ShaderFxData *next_fx;
+
+ next_fx = fx->next;
+
+ object_shaderfx_remove(bmain, ob, fx, &sort_depsgraph);
+
+ fx = next_fx;
+ }
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ DEG_relations_tag_update(bmain);
+}
+
+int ED_object_shaderfx_move_up(ReportList *UNUSED(reports), Object *ob, ShaderFxData *fx)
+{
+ if (fx->prev) {
+ BLI_remlink(&ob->shader_fx, fx);
+ BLI_insertlinkbefore(&ob->shader_fx, fx->prev, fx);
+ }
+
+ return 1;
+}
+
+int ED_object_shaderfx_move_down(ReportList *UNUSED(reports), Object *ob, ShaderFxData *fx)
+{
+ if (fx->next) {
+ BLI_remlink(&ob->shader_fx, fx);
+ BLI_insertlinkafter(&ob->shader_fx, fx->next, fx);
+ }
+
+ return 1;
+}
+
+/************************ add effect operator *********************/
+
+static int shaderfx_add_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = ED_object_active_context(C);
+ int type = RNA_enum_get(op->ptr, "type");
+
+ if (!ED_object_shaderfx_add(op->reports, bmain, scene, ob, NULL, type))
+ return OPERATOR_CANCELLED;
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static const EnumPropertyItem *shaderfx_add_itemf(
+ bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ Object *ob = ED_object_active_context(C);
+ EnumPropertyItem *item = NULL;
+ const EnumPropertyItem *fx_item, *group_item = NULL;
+ const ShaderFxTypeInfo *mti;
+ int totitem = 0, a;
+
+ if (!ob)
+ return rna_enum_object_shaderfx_type_items;
+
+ for (a = 0; rna_enum_object_shaderfx_type_items[a].identifier; a++) {
+ fx_item = &rna_enum_object_shaderfx_type_items[a];
+ if (fx_item->identifier[0]) {
+ mti = BKE_shaderfxType_getInfo(fx_item->value);
+
+ if (mti->flags & eShaderFxTypeFlag_NoUserAdd)
+ continue;
+ }
+ else {
+ group_item = fx_item;
+ fx_item = NULL;
+
+ continue;
+ }
+
+ if (group_item) {
+ RNA_enum_item_add(&item, &totitem, group_item);
+ group_item = NULL;
+ }
+
+ RNA_enum_item_add(&item, &totitem, fx_item);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+void OBJECT_OT_shaderfx_add(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Add Effect";
+ ot->description = "Add a visual effect to the active object";
+ ot->idname = "OBJECT_OT_shaderfx_add";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = shaderfx_add_exec;
+ ot->poll = ED_operator_object_active_editable;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_enum(ot->srna, "type", rna_enum_object_shaderfx_type_items, eShaderFxType_Blur, "Type", "");
+ RNA_def_enum_funcs(prop, shaderfx_add_itemf);
+ ot->prop = prop;
+}
+
+/************************ generic functions for operators using names and data context *********************/
+
+static bool edit_shaderfx_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
+{
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "shaderfx", rna_type);
+ Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);
+
+ if (!ptr.data) {
+ CTX_wm_operator_poll_msg_set(C, "Context missing 'shaderfx'");
+ return 0;
+ }
+
+ if (!ob || ID_IS_LINKED(ob)) return 0;
+ if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) return 0;
+ if (ptr.id.data && ID_IS_LINKED(ptr.id.data)) return 0;
+
+ if (ID_IS_STATIC_OVERRIDE(ob)) {
+ CTX_wm_operator_poll_msg_set(C, "Cannot edit shaderfxs comming from static override");
+ return (((ShaderFxData *)ptr.data)->flag & eShaderFxFlag_StaticOverride_Local) != 0;
+ }
+
+ return 1;
+}
+
+static bool edit_shaderfx_poll(bContext *C)
+{
+ return edit_shaderfx_poll_generic(C, &RNA_ShaderFx, 0);
+}
+
+static void edit_shaderfx_properties(wmOperatorType *ot)
+{
+ RNA_def_string(ot->srna, "shaderfx", NULL, MAX_NAME, "Shader", "Name of the shaderfx to edit");
+}
+
+static int edit_shaderfx_invoke_properties(bContext *C, wmOperator *op)
+{
+ ShaderFxData *fx;
+
+ if (RNA_struct_property_is_set(op->ptr, "shaderfx")) {
+ return true;
+ }
+ else {
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "shaderfx", &RNA_ShaderFx);
+ if (ptr.data) {
+ fx = ptr.data;
+ RNA_string_set(op->ptr, "shaderfx", fx->name);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static ShaderFxData *edit_shaderfx_property_get(wmOperator *op, Object *ob, int type)
+{
+ char shaderfx_name[MAX_NAME];
+ ShaderFxData *fx;
+ RNA_string_get(op->ptr, "shaderfx", shaderfx_name);
+
+ fx = BKE_shaderfx_findByName(ob, shaderfx_name);
+
+ if (fx && type != 0 && fx->type != type)
+ fx = NULL;
+
+ return fx;
+}
+
+/************************ remove shaderfx operator *********************/
+
+static int shaderfx_remove_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob = ED_object_active_context(C);
+ ShaderFxData *fx = edit_shaderfx_property_get(op, ob, 0);
+
+ if (!fx || !ED_object_shaderfx_remove(op->reports, bmain, ob, fx))
+ return OPERATOR_CANCELLED;
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int shaderfx_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (edit_shaderfx_invoke_properties(C, op))
+ return shaderfx_remove_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+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->idname = "OBJECT_OT_shaderfx_remove";
+
+ ot->invoke = shaderfx_remove_invoke;
+ ot->exec = shaderfx_remove_exec;
+ ot->poll = edit_shaderfx_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ edit_shaderfx_properties(ot);
+}
+
+/************************ move up shaderfx operator *********************/
+
+static int shaderfx_move_up_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_active_context(C);
+ ShaderFxData *fx = edit_shaderfx_property_get(op, ob, 0);
+
+ if (!fx || !ED_object_shaderfx_move_up(op->reports, ob, fx))
+ return OPERATOR_CANCELLED;
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int shaderfx_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (edit_shaderfx_invoke_properties(C, op))
+ return shaderfx_move_up_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_shaderfx_move_up(wmOperatorType *ot)
+{
+ ot->name = "Move Up Modifier";
+ ot->description = "Move shaderfx up in the stack";
+ ot->idname = "OBJECT_OT_shaderfx_move_up";
+
+ ot->invoke = shaderfx_move_up_invoke;
+ ot->exec = shaderfx_move_up_exec;
+ ot->poll = edit_shaderfx_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ edit_shaderfx_properties(ot);
+}
+
+/************************ move down shaderfx operator *********************/
+
+static int shaderfx_move_down_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_active_context(C);
+ ShaderFxData *fx = edit_shaderfx_property_get(op, ob, 0);
+
+ if (!fx || !ED_object_shaderfx_move_down(op->reports, ob, fx))
+ return OPERATOR_CANCELLED;
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int shaderfx_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (edit_shaderfx_invoke_properties(C, op))
+ return shaderfx_move_down_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_shaderfx_move_down(wmOperatorType *ot)
+{
+ ot->name = "Move Down Modifier";
+ ot->description = "Move shaderfx down in the stack";
+ ot->idname = "OBJECT_OT_shaderfx_move_down";
+
+ ot->invoke = shaderfx_move_down_invoke;
+ ot->exec = shaderfx_move_down_exec;
+ ot->poll = edit_shaderfx_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ edit_shaderfx_properties(ot);
+}
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 5e66dc00fd2..30fb2896670 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -378,8 +378,10 @@ static int shape_key_retime_exec(bContext *C, wmOperator *UNUSED(op))
if (!key || !kb)
return OPERATOR_CANCELLED;
- for (kb = key->block.first; kb; kb = kb->next)
- kb->pos = (cfra += 0.1f);
+ for (kb = key->block.first; kb; kb = kb->next) {
+ kb->pos = cfra;
+ cfra += 0.1f;
+ }
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index d2a0879464b..96b540251b4 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -38,6 +38,7 @@
#include "DNA_lamp_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_group_types.h"
#include "DNA_lattice_types.h"
@@ -59,6 +60,7 @@
#include "BKE_armature.h"
#include "BKE_lattice.h"
#include "BKE_tracking.h"
+#include "BKE_gpencil.h"
#include "DEG_depsgraph.h"
@@ -73,6 +75,7 @@
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_view3d.h"
+#include "ED_gpencil.h"
#include "MEM_guardedalloc.h"
@@ -434,7 +437,7 @@ static int apply_objects_internal(
/* first check if we can execute */
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
- if (ELEM(ob->type, OB_MESH, OB_ARMATURE, OB_LATTICE, OB_MBALL, OB_CURVE, OB_SURF, OB_FONT)) {
+ if (ELEM(ob->type, OB_MESH, OB_ARMATURE, OB_LATTICE, OB_MBALL, OB_CURVE, OB_SURF, OB_FONT, OB_GPENCIL)) {
ID *obdata = ob->data;
if (ID_REAL_USERS(obdata) > 1) {
BKE_reportf(reports, RPT_ERROR,
@@ -480,6 +483,37 @@ static int apply_objects_internal(
}
}
+ if (ob->type == OB_GPENCIL) {
+ bGPdata *gpd = ob->data;
+ if (gpd) {
+ if (gpd->layers.first) {
+ /* Unsupported configuration */
+ bool has_unparented_layers = false;
+
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ /* Parented layers aren't supported as we can't easily re-evaluate the scene to sample parent movement */
+ if (gpl->parent == NULL) {
+ has_unparented_layers = true;
+ break;
+ }
+ }
+
+ if (has_unparented_layers == false) {
+ BKE_reportf(reports, RPT_ERROR,
+ "Can't apply to a GP datablock where all layers are parented: Object \"%s\", %s \"%s\", aborting",
+ ob->id.name + 2, BKE_idcode_to_name(ID_GD), gpd->id.name + 2);
+ changed = false;
+ }
+ }
+ else {
+ /* No layers/data */
+ BKE_reportf(reports, RPT_ERROR,
+ "Can't apply to GP datablock with no layers: Object \"%s\", %s \"%s\", aborting",
+ ob->id.name + 2, BKE_idcode_to_name(ID_GD), gpd->id.name + 2);
+ }
+ }
+ }
+
if (ob->type == OB_LAMP) {
Lamp *la = ob->data;
if (la->type == LA_AREA) {
@@ -587,6 +621,10 @@ static int apply_objects_internal(
cu->fsize *= scale;
}
}
+ else if (ob->type == OB_GPENCIL) {
+ bGPdata *gpd = ob->data;
+ BKE_gpencil_transform(gpd, mat);
+ }
else if (ob->type == OB_CAMERA) {
MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
@@ -1056,6 +1094,69 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
lt->id.tag |= LIB_TAG_DOIT;
do_inverse_offset = true;
}
+ else if (ob->type == OB_GPENCIL) {
+ bGPdata *gpd = ob->data;
+ float gpcenter[3];
+ if (gpd) {
+ if (centermode == ORIGIN_TO_GEOMETRY) {
+ zero_v3(gpcenter);
+ BKE_gpencil_centroid_3D(gpd, gpcenter);
+ add_v3_v3(gpcenter, ob->obmat[3]);
+ }
+ if (centermode == ORIGIN_TO_CURSOR) {
+ copy_v3_v3(gpcenter, cursor);
+ }
+ if ((centermode == ORIGIN_TO_GEOMETRY) || (centermode == ORIGIN_TO_CURSOR)) {
+ bGPDspoint *pt;
+ float imat[3][3], bmat[3][3];
+ float offset_global[3];
+ float offset_local[3];
+ int i;
+
+ sub_v3_v3v3(offset_global, gpcenter, ob->obmat[3]);
+ copy_m3_m4(bmat, obact->obmat);
+ invert_m3_m3(imat, bmat);
+ mul_m3_v3(imat, offset_global);
+ mul_v3_m3v3(offset_local, imat, offset_global);
+
+ float diff_mat[4][4];
+ float inverse_diff_mat[4][4];
+
+ /* recalculate all strokes (all layers are considered without evaluating lock attributtes) */
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ /* calculate difference matrix */
+ ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat);
+ /* undo matrix */
+ invert_m4_m4(inverse_diff_mat, diff_mat);
+ for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ float mpt[3];
+ mul_v3_m4v3(mpt, inverse_diff_mat, &pt->x);
+ sub_v3_v3(mpt, offset_local);
+ mul_v3_m4v3(&pt->x, diff_mat, mpt);
+ }
+ }
+ }
+ }
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+
+ tot_change++;
+ if (centermode == ORIGIN_TO_GEOMETRY) {
+ copy_v3_v3(ob->loc, gpcenter);
+ }
+ ob->id.tag |= LIB_TAG_DOIT;
+ do_inverse_offset = true;
+ }
+ else {
+ BKE_report(op->reports, RPT_WARNING, "Grease Pencil Object does not support this set origin option");
+ }
+ }
+ }
/* offset other selected objects */
if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) {
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 10d9c90aeb3..1b82e60b986 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -2892,7 +2892,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)
brush = &pset->brush[pset->brushtype];
if (brush) {
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ub(255, 255, 255, 128);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index b5c1ffc64dd..ed7950f3993 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -326,10 +326,10 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT);
wmOrtho2(0, sizex, 0, sizey);
- gpuTranslate2f(sizex / 2, sizey / 2);
+ GPU_matrix_translate_2f(sizex / 2, sizey / 2);
G.f |= G_RENDER_OGL;
- ED_gpencil_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ);
+ ED_gpencil_draw_ex(rv3d, scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ);
G.f &= ~G_RENDER_OGL;
gp_rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect");
@@ -355,7 +355,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
if (view_context) {
ibuf_view = ED_view3d_draw_offscreen_imbuf(
- depsgraph, scene, v3d->drawtype,
+ depsgraph, scene, v3d->shading.type,
v3d, ar, sizex, sizey,
IB_rectfloat, draw_flags, alpha_mode, oglrender->ofs_samples, viewname,
oglrender->ofs, err_out);
@@ -417,7 +417,7 @@ static void screen_opengl_render_write(OGLRender *oglrender)
else printf("OpenGL Render failed to write '%s'\n", name);
}
-static void addAlphaOverFloat(float dest[4], const float source[4])
+static void UNUSED_FUNCTION(addAlphaOverFloat)(float dest[4], const float source[4])
{
/* d = s + (1-alpha_s)d*/
float mul;
@@ -431,91 +431,6 @@ static void addAlphaOverFloat(float dest[4], const float source[4])
}
-/* add renderlayer and renderpass for each grease pencil layer for using in composition */
-static void add_gpencil_renderpass(const bContext *C, OGLRender *oglrender, RenderResult *rr, RenderView *rv)
-{
- bGPdata *gpd = oglrender->scene->gpd;
- Scene *scene = oglrender->scene;
-
- /* sanity checks */
- if (gpd == NULL) {
- return;
- }
- if (scene == NULL) {
- return;
- }
- if (BLI_listbase_is_empty(&gpd->layers)) {
- return;
- }
- if (oglrender->v3d != NULL && (oglrender->v3d->flag2 & V3D_SHOW_GPENCIL) == 0) {
- return;
- }
-
- /* save old alpha mode */
- short oldalphamode = scene->r.alphamode;
- /* set alpha transparent for gp */
- scene->r.alphamode = R_ALPHAPREMUL;
-
- /* saves layer status */
- short *oldsts = MEM_mallocN(BLI_listbase_count(&gpd->layers) * sizeof(short), "temp_gplayers_flag");
- int i = 0;
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- oldsts[i] = gpl->flag;
- ++i;
- }
- /* loop all layers to create separate render */
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- /* dont draw layer if hidden */
- if (gpl->flag & GP_LAYER_HIDE)
- continue;
- /* hide all layer except current */
- for (bGPDlayer *gph = gpd->layers.first; gph; gph = gph->next) {
- if (gpl != gph) {
- gph->flag |= GP_LAYER_HIDE;
- }
- }
-
- /* render this gp layer */
- screen_opengl_render_doit(C, oglrender, rr);
-
- /* add RendePass composite */
- RenderPass *rp = RE_create_gp_pass(rr, gpl->info, rv->name);
-
- /* copy image data from rectf */
- // XXX: Needs conversion.
- unsigned char *src = (unsigned char *)RE_RenderViewGetById(rr, oglrender->view_id)->rect32;
- if (src != NULL) {
- float *dest = rp->rect;
-
- int x, y, rectx, recty;
- rectx = rr->rectx;
- recty = rr->recty;
- for (y = 0; y < recty; y++) {
- for (x = 0; x < rectx; x++) {
- unsigned char *pixSrc = src + 4 * (rectx * y + x);
- if (pixSrc[3] > 0) {
- float *pixDest = dest + 4 * (rectx * y + x);
- float float_src[4];
- srgb_to_linearrgb_uchar4(float_src, pixSrc);
- addAlphaOverFloat(pixDest, float_src);
- }
- }
- }
- }
- /* back layer status */
- i = 0;
- for (bGPDlayer *gph = gpd->layers.first; gph; gph = gph->next) {
- gph->flag = oldsts[i];
- ++i;
- }
- }
- /* free memory */
- MEM_freeN(oldsts);
-
- /* back default alpha mode */
- scene->r.alphamode = oldalphamode;
-}
-
static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender)
{
RenderResult *rr;
@@ -550,11 +465,6 @@ static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender)
BLI_assert(view_id < oglrender->views_len);
RE_SetActiveRenderView(oglrender->re, rv->name);
oglrender->view_id = view_id;
- /* add grease pencil passes. For sequencer, the render does not include renderpasses
- * TODO: The sequencer render of grease pencil should be rethought */
- if (!oglrender->is_sequencer) {
- add_gpencil_renderpass(C, oglrender, rr, rv);
- }
/* render composite */
screen_opengl_render_doit(C, oglrender, rr);
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 04632838cf3..8bb60b19dcf 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -158,7 +158,7 @@ typedef struct ShaderPreview {
Scene *scene;
Depsgraph *depsgraph;
- ID *id;
+ ID *id, *id_copy;
ID *parent;
MTex *slot;
@@ -173,6 +173,7 @@ typedef struct ShaderPreview {
int sizex, sizey;
unsigned int *pr_rect;
int pr_method;
+ bool own_id_copy;
Main *bmain;
Main *pr_main;
@@ -189,7 +190,7 @@ typedef struct IconPreview {
Scene *scene;
Depsgraph *depsgraph;
void *owner;
- ID *id;
+ ID *id, *id_copy;
ListBase sizes;
} IconPreview;
@@ -197,6 +198,7 @@ typedef struct IconPreview {
static Main *G_pr_main = NULL;
static Main *G_pr_main_cycles = NULL;
+static Main *G_pr_main_grease_pencil = NULL;
#ifndef WITH_HEADLESS
static Main *load_main_from_memory(const void *blend, int blend_size)
@@ -226,6 +228,7 @@ void ED_preview_ensure_dbase(void)
if (!base_initialized) {
G_pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size);
G_pr_main_cycles = load_main_from_memory(datatoc_preview_cycles_blend, datatoc_preview_cycles_blend_size);
+ G_pr_main_grease_pencil = load_main_from_memory(datatoc_preview_grease_pencil_blend, datatoc_preview_grease_pencil_blend_size);
base_initialized = true;
}
#endif
@@ -234,7 +237,13 @@ void ED_preview_ensure_dbase(void)
static bool check_engine_supports_textures(Scene *scene)
{
RenderEngineType *type = RE_engines_find(scene->r.engine);
- return type->flag & RE_USE_TEXTURE_PREVIEW;
+ return (type->flag & RE_USE_TEXTURE_PREVIEW) != 0;
+}
+
+static bool check_engine_supports_preview(Scene *scene)
+{
+ RenderEngineType *type = RE_engines_find(scene->r.engine);
+ return (type->flag & RE_USE_PREVIEW) != 0;
}
void ED_preview_free_dbase(void)
@@ -244,6 +253,9 @@ void ED_preview_free_dbase(void)
if (G_pr_main_cycles)
BKE_main_free(G_pr_main_cycles);
+
+ if (G_pr_main_grease_pencil)
+ BKE_main_free(G_pr_main_grease_pencil);
}
static Scene *preview_get_scene(Main *pr_main)
@@ -312,6 +324,38 @@ static World *preview_get_localized_world(ShaderPreview *sp, World *world)
return sp->worldcopy;
}
+static ID *duplicate_ids(ID *id, Depsgraph *depsgraph)
+{
+ if (id == NULL) {
+ /* Non-ID preview render. */
+ return NULL;
+ }
+
+ ID *id_eval = id;
+
+ if (depsgraph) {
+ id_eval = DEG_get_evaluated_id(depsgraph, id);
+ }
+
+ switch (GS(id->name)) {
+ case ID_MA:
+ return (ID *)BKE_material_localize((Material *)id_eval);
+ case ID_TE:
+ return (ID *)BKE_texture_localize((Tex *)id_eval);
+ case ID_LA:
+ return (ID *)BKE_lamp_localize((Lamp *)id_eval);
+ case ID_WO:
+ return (ID *)BKE_world_localize((World *)id_eval);
+ case ID_IM:
+ case ID_BR:
+ case ID_SCR:
+ return NULL;
+ default:
+ BLI_assert(!"ID type preview not supported.");
+ return NULL;
+ }
+}
+
/* call this with a pointer to initialize preview scene */
/* call this with NULL to restore assigned ID pointers in preview scene */
static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_type, ShaderPreview *sp)
@@ -373,8 +417,9 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
if (origmat) {
/* work on a copy */
- mat = BKE_material_localize(origmat);
- sp->matcopy = mat;
+ BLI_assert(sp->id_copy != NULL);
+ mat = sp->matcopy = (Material *)sp->id_copy;
+ sp->id_copy = NULL;
BLI_addtail(&pr_main->mat, mat);
/* use current scene world to light sphere */
@@ -400,13 +445,13 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
if (mat->nodetree && sp->pr_method == PR_NODE_RENDER) {
/* two previews, they get copied by wmJob */
BKE_node_preview_init_tree(mat->nodetree, sp->sizex, sp->sizey, true);
+ /* WATCH: Accessing origmat is not safe! */
BKE_node_preview_init_tree(origmat->nodetree, sp->sizex, sp->sizey, true);
}
}
}
else {
sce->r.mode &= ~(R_OSA);
-
}
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
@@ -432,16 +477,18 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
Tex *tex = NULL, *origtex = (Tex *)id;
if (origtex) {
- tex = BKE_texture_localize(origtex);
- sp->texcopy = tex;
+ BLI_assert(sp->id_copy != NULL);
+ tex = sp->texcopy = (Tex *)sp->id_copy;
+ sp->id_copy = NULL;
BLI_addtail(&pr_main->tex, tex);
}
set_preview_collection(sce, view_layer, MA_TEXTURE);
if (tex && tex->nodetree && sp->pr_method == PR_NODE_RENDER) {
/* two previews, they get copied by wmJob */
- BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, true);
BKE_node_preview_init_tree(tex->nodetree, sp->sizex, sp->sizey, true);
+ /* WATCH: Accessing origtex is not safe! */
+ BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, true);
}
}
else if (id_type == ID_LA) {
@@ -449,8 +496,9 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
/* work on a copy */
if (origla) {
- la = BKE_lamp_localize(origla);
- sp->lampcopy = la;
+ BLI_assert(sp->id_copy != NULL);
+ la = sp->lampcopy = (Lamp *)sp->id_copy;
+ sp->id_copy = NULL;
BLI_addtail(&pr_main->lamp, la);
}
@@ -473,16 +521,18 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
if (la && la->nodetree && sp->pr_method == PR_NODE_RENDER) {
/* two previews, they get copied by wmJob */
- BKE_node_preview_init_tree(origla->nodetree, sp->sizex, sp->sizey, true);
BKE_node_preview_init_tree(la->nodetree, sp->sizex, sp->sizey, true);
+ /* WATCH: Accessing origla is not safe! */
+ BKE_node_preview_init_tree(origla->nodetree, sp->sizex, sp->sizey, true);
}
}
else if (id_type == ID_WO) {
World *wrld = NULL, *origwrld = (World *)id;
if (origwrld) {
- wrld = BKE_world_localize(origwrld);
- sp->worldcopy = wrld;
+ BLI_assert(sp->id_copy != NULL);
+ wrld = sp->worldcopy = (World *)sp->id_copy;
+ sp->id_copy = NULL;
BLI_addtail(&pr_main->world, wrld);
}
@@ -492,6 +542,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
if (wrld && wrld->nodetree && sp->pr_method == PR_NODE_RENDER) {
/* two previews, they get copied by wmJob */
BKE_node_preview_init_tree(wrld->nodetree, sp->sizex, sp->sizey, true);
+ /* WATCH: Accessing origwrld is not safe! */
BKE_node_preview_init_tree(origwrld->nodetree, sp->sizex, sp->sizey, true);
}
}
@@ -685,7 +736,11 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
char name[32];
int sizex;
Main *pr_main = sp->pr_main;
- ID *id_eval = DEG_get_evaluated_id(sp->depsgraph, id);
+ ID *id_eval = id;
+
+ if (sp->depsgraph) {
+ id_eval = DEG_get_evaluated_id(sp->depsgraph, id);
+ }
/* in case of split preview, use border render */
if (split) {
@@ -704,6 +759,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
sce->r.size = 100;
}
+
/* get the stuff from the builtin preview dbase */
sce = preview_prepare_scene(sp->bmain, sp->scene, id_eval, idtype, sp);
if (sce == NULL) return;
@@ -795,70 +851,51 @@ static void shader_preview_free(void *customdata)
Main *pr_main = sp->pr_main;
if (sp->matcopy) {
- struct IDProperty *properties;
-
- /* node previews */
- shader_preview_updatejob(sp);
-
- /* get rid of copied material */
+ sp->id_copy = (ID *)sp->matcopy;
BLI_remlink(&pr_main->mat, sp->matcopy);
-
- BKE_material_free(sp->matcopy);
-
- properties = IDP_GetProperties((ID *)sp->matcopy, false);
- if (properties) {
- IDP_FreeProperty(properties);
- MEM_freeN(properties);
- }
- MEM_freeN(sp->matcopy);
}
if (sp->texcopy) {
- struct IDProperty *properties;
- /* node previews */
- shader_preview_updatejob(sp);
-
- /* get rid of copied texture */
+ sp->id_copy = (ID *)sp->texcopy;
BLI_remlink(&pr_main->tex, sp->texcopy);
- BKE_texture_free(sp->texcopy);
-
- properties = IDP_GetProperties((ID *)sp->texcopy, false);
- if (properties) {
- IDP_FreeProperty(properties);
- MEM_freeN(properties);
- }
- MEM_freeN(sp->texcopy);
}
if (sp->worldcopy) {
- struct IDProperty *properties;
- /* node previews */
- shader_preview_updatejob(sp);
-
- /* get rid of copied world */
+ sp->id_copy = (ID *)sp->worldcopy;
BLI_remlink(&pr_main->world, sp->worldcopy);
- BKE_world_free(sp->worldcopy);
-
- properties = IDP_GetProperties((ID *)sp->worldcopy, false);
- if (properties) {
- IDP_FreeProperty(properties);
- MEM_freeN(properties);
- }
- MEM_freeN(sp->worldcopy);
}
if (sp->lampcopy) {
- struct IDProperty *properties;
+ sp->id_copy = (ID *)sp->lampcopy;
+ BLI_remlink(&pr_main->lamp, sp->lampcopy);
+ }
+ if (sp->id_copy) {
/* node previews */
shader_preview_updatejob(sp);
-
- /* get rid of copied lamp */
- BLI_remlink(&pr_main->lamp, sp->lampcopy);
- BKE_lamp_free(sp->lampcopy);
-
- properties = IDP_GetProperties((ID *)sp->lampcopy, false);
+ }
+ if (sp->id_copy && sp->own_id_copy) {
+ struct IDProperty *properties;
+ /* get rid of copied ID */
+ properties = IDP_GetProperties(sp->id_copy, false);
if (properties) {
IDP_FreeProperty(properties);
MEM_freeN(properties);
}
- MEM_freeN(sp->lampcopy);
+ switch (GS(sp->id_copy->name)) {
+ case ID_MA:
+ BKE_material_free((Material *)sp->id_copy);
+ break;
+ case ID_TE:
+ BKE_texture_free((Tex *)sp->id_copy);
+ break;
+ case ID_LA:
+ BKE_lamp_free((Lamp *)sp->id_copy);
+ break;
+ case ID_WO:
+ BKE_world_free((World *)sp->id_copy);
+ break;
+ default:
+ BLI_assert(!"ID type preview not supported.");
+ break;
+ }
+ MEM_freeN(sp->id_copy);
}
MEM_freeN(sp);
@@ -1062,6 +1099,10 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short
continue;
}
+ if (!check_engine_supports_preview(ip->scene)) {
+ continue;
+ }
+
ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
const bool is_render = !(prv->tag & PRV_TAG_DEFFERED);
@@ -1074,7 +1115,10 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short
sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED;
sp->pr_rect = cur_size->rect;
sp->id = ip->id;
+ sp->id_copy = ip->id_copy;
sp->bmain = ip->bmain;
+ sp->own_id_copy = false;
+ Material *ma = NULL;
if (is_render) {
BLI_assert(ip->id);
@@ -1082,10 +1126,22 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short
* so don't even think of using cycle's bmain for
* texture icons
*/
- if (GS(ip->id->name) != ID_TE)
- sp->pr_main = G_pr_main_cycles;
- else
+ if (GS(ip->id->name) != ID_TE) {
+ /* grease pencil use its own preview file */
+ if (GS(ip->id->name) == ID_MA) {
+ ma = (Material *)ip->id;
+ }
+
+ if ((ma == NULL) || (ma->gp_style == NULL)) {
+ sp->pr_main = G_pr_main_cycles;
+ }
+ else {
+ sp->pr_main = G_pr_main_grease_pencil;
+ }
+ }
+ else {
sp->pr_main = G_pr_main;
+ }
}
common_preview_startjob(sp, stop, do_update, progress);
@@ -1133,6 +1189,15 @@ static void icon_preview_free(void *customdata)
{
IconPreview *ip = (IconPreview *)customdata;
+ if (ip->id_copy) {
+ /* Feels a bit hacky just to reuse shader_preview_free() */
+ ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
+ sp->id_copy = ip->id_copy;
+ sp->own_id_copy = true;
+ shader_preview_free(sp);
+ ip->id_copy = NULL;
+ }
+
BLI_freelistN(&ip->sizes);
MEM_freeN(ip);
}
@@ -1149,6 +1214,7 @@ void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, unsigned int *rec
ip.scene = scene;
ip.owner = BKE_previewimg_id_ensure(id);
ip.id = id;
+ ip.id_copy = duplicate_ids(id, NULL);
icon_preview_add_size(&ip, rect, sizex, sizey);
@@ -1183,6 +1249,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r
ip->depsgraph = CTX_data_depsgraph(C);
ip->owner = owner;
ip->id = id;
+ ip->id_copy = duplicate_ids(id, ip->depsgraph);
icon_preview_add_size(ip, rect, sizex, sizey);
@@ -1212,6 +1279,10 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
/* Use workspace render only for buttons Window, since the other previews are related to the datablock. */
+ if (!check_engine_supports_preview(scene)) {
+ return;
+ }
+
/* Only texture node preview is supported with Cycles. */
if (method == PR_NODE_RENDER && id_type != ID_TE) {
return;
@@ -1231,14 +1302,28 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
sp->sizey = sizey;
sp->pr_method = method;
sp->id = id;
+ sp->id_copy = duplicate_ids(id, sp->depsgraph);
+ sp->own_id_copy = true;
sp->parent = parent;
sp->slot = slot;
sp->bmain = CTX_data_main(C);
+ Material *ma = NULL;
/* hardcoded preview .blend for Eevee + Cycles, this should be solved
* once with custom preview .blend path for external engines */
if ((method != PR_NODE_RENDER) && id_type != ID_TE) {
- sp->pr_main = G_pr_main_cycles;
+ /* grease pencil use its own preview file */
+ if (GS(id->name) == ID_MA) {
+ ma = (Material *)id;
+ }
+
+ if ((ma == NULL) || (ma->gp_style == NULL)) {
+ sp->pr_main = G_pr_main_cycles;
+ }
+ else {
+ sp->pr_main = G_pr_main_grease_pencil;
+ }
+
}
else {
sp->pr_main = G_pr_main;
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 8077079a9b5..2dd4f328d06 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -469,6 +469,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
{
Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
Main *bmain = CTX_data_main(C);
+ Object *ob = CTX_data_active_object(C);
PointerRNA ptr, idptr;
PropertyRNA *prop;
@@ -477,7 +478,12 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
ma = BKE_material_copy(bmain, ma);
}
else {
- ma = BKE_material_add(bmain, DATA_("Material"));
+ if ((!ob) || (ob->type != OB_GPENCIL)) {
+ ma = BKE_material_add(bmain, DATA_("Material"));
+ }
+ else {
+ ma = BKE_material_add_gpencil(bmain, DATA_("Material"));
+ }
ED_node_shader_default(C, &ma->id);
ma->use_nodes = true;
}
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index e473b98b4a1..09d89e3b90f 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -144,7 +144,7 @@ void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int update
}
else {
RenderEngineType *engine_type =
- ED_view3d_engine_type(scene, v3d->drawtype);
+ ED_view3d_engine_type(scene, v3d->shading.type);
if (updated) {
DRW_notify_view_update(
(&(DRWUpdateContext){
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 41c3209dbb1..18bacee98b9 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -105,12 +105,12 @@ static void region_draw_emboss(const ARegion *ar, const rcti *scirct, int sides)
float color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
UI_GetThemeColor3fv(TH_EDITOR_OUTLINE, color);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(color);
- immBeginAtMost(GWN_PRIM_LINES, 8);
+ immBeginAtMost(GPU_PRIM_LINES, 8);
/* right */
if (sides & REGION_EMBOSS_RIGHT) {
@@ -146,7 +146,7 @@ static void region_draw_emboss(const ARegion *ar, const rcti *scirct, int sides)
void ED_region_pixelspace(ARegion *ar)
{
wmOrtho2_region_pixelspace(ar);
- gpuLoadIdentity();
+ GPU_matrix_identity_set();
}
/* only exported for WM */
@@ -262,8 +262,8 @@ static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, f
BLI_rcti_init(&click_rect, x, x + icon_size, y, y + icon_size);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -271,7 +271,7 @@ static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, f
imm_draw_box_wire_2d(pos, click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax);
immUniformColor4f(0.0f, 1.0f, 1.0f, alpha);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, click_rect.xmin, click_rect.ymin);
immVertex2f(pos, click_rect.xmax, click_rect.ymax);
immVertex2f(pos, click_rect.xmin, click_rect.ymax);
@@ -295,8 +295,8 @@ static void draw_azone_plus(float x1, float y1, float x2, float y2)
float width = 0.1f * U.widget_unit;
float pad = 0.2f * U.widget_unit;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
GPU_blend(true);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -352,8 +352,8 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar)
GPU_blend(true);
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- gpuPushMatrix();
- gpuTranslate2f(-ar->winrct.xmin, -ar->winrct.ymin);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(-ar->winrct.xmin, -ar->winrct.ymin);
for (az = sa->actionzones.first; az; az = az->next) {
/* test if action zone is over this region */
@@ -388,7 +388,7 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar)
}
}
- gpuPopMatrix();
+ GPU_matrix_pop();
GPU_blend(false);
}
@@ -500,8 +500,8 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
/* for debugging unneeded area redraws and partial redraw */
#if 0
GPU_blend(true);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4f(drand48(), drand48(), drand48(), 0.1f);
immRectf(pos, ar->drawrct.xmin - ar->winrct.xmin, ar->drawrct.ymin - ar->winrct.ymin,
@@ -1428,18 +1428,32 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
}
if (flag & ED_KEYMAP_GPENCIL) {
/* grease pencil */
- /* NOTE: This is now 2 keymaps - One for basic functionality,
- * and one that only applies when "Edit Mode" is enabled
- * for strokes.
+ /* NOTE: This is now 4 keymaps - One for basic functionality,
+ * and others for special stroke modes (edit, paint and sculpt).
*
- * For now, it's easier to just include both,
- * since you hardly want one without the other.
+ * For now, it's easier to just include all,
+ * since you hardly want one without the others.
*/
wmKeyMap *keymap_general = WM_keymap_find(wm->defaultconf, "Grease Pencil", 0, 0);
- wmKeyMap *keymap_edit = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Edit Mode", 0, 0);
-
WM_event_add_keymap_handler(handlers, keymap_general);
+
+ wmKeyMap *keymap_edit = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Edit Mode", 0, 0);
WM_event_add_keymap_handler(handlers, keymap_edit);
+
+ wmKeyMap *keymap_paint = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Paint Mode", 0, 0);
+ WM_event_add_keymap_handler(handlers, keymap_paint);
+
+ wmKeyMap *keymap_paint_draw = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Paint (Draw brush)", 0, 0);
+ WM_event_add_keymap_handler(handlers, keymap_paint_draw);
+
+ wmKeyMap *keymap_paint_erase = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Paint (Erase)", 0, 0);
+ WM_event_add_keymap_handler(handlers, keymap_paint_erase);
+
+ wmKeyMap *keymap_paint_fill = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Paint (Fill)", 0, 0);
+ WM_event_add_keymap_handler(handlers, keymap_paint_fill);
+
+ wmKeyMap *keymap_sculpt = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Sculpt Mode", 0, 0);
+ WM_event_add_keymap_handler(handlers, keymap_sculpt);
}
if (flag & ED_KEYMAP_HEADER) {
/* standard keymap for headers regions */
@@ -2472,8 +2486,8 @@ void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float
GPU_blend(true);
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(fill_color);
immRecti(pos, rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1);
@@ -2674,11 +2688,11 @@ void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame,
return;
/* find window pixel coordinates of origin */
- gpuPushMatrix();
+ GPU_matrix_push();
/* offset and zoom using ogl */
- gpuTranslate2f(x, y);
- gpuScale2f(zoomx, zoomy);
+ GPU_matrix_translate_2f(x, y);
+ GPU_matrix_scale_2f(zoomx, zoomy);
BLF_size(blf_mono_font, style->widgetlabel.points * 1.5f * U.pixelsize, U.dpi);
@@ -2691,8 +2705,8 @@ void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame,
/* set up rect */
BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymax, frame->ymax + box_y);
/* draw top box */
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ 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_METADATA_BG);
immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
@@ -2716,8 +2730,8 @@ void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame,
/* set up box rect */
BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymin - box_y, frame->ymin);
/* draw top box */
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ 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_METADATA_BG);
immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
@@ -2732,7 +2746,7 @@ void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame,
BLF_disable(blf_mono_font, BLF_CLIPPING);
}
- gpuPopMatrix();
+ GPU_matrix_pop();
}
void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
@@ -2745,8 +2759,8 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x1, &y1);
UI_view2d_view_to_region(&ar->v2d, 1.0f, 1.0f, &x2, &y2);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShade(TH_BACK, 20);
@@ -2778,12 +2792,12 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
int count_large = 1.0f / (4.0f * gridstep);
if (count_fine > 0) {
- GWN_vertformat_clear(format);
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- unsigned color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPU_vertformat_clear(format);
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ unsigned color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GWN_PRIM_LINES, 4 * count_fine + 4 * count_large);
+ immBegin(GPU_PRIM_LINES, 4 * count_fine + 4 * count_large);
float theme_color[3];
UI_GetThemeColorShade3fv(TH_BACK, (int)(20.0f * (1.0f - blendfac)), theme_color);
@@ -2877,7 +2891,7 @@ void ED_region_visible_rect(ARegion *ar, rcti *rect)
void ED_region_cache_draw_background(const ARegion *ar)
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ub(128, 128, 255, 64);
immRecti(pos, 0, 0, ar->winx, 8 * UI_DPI_FAC);
@@ -2897,7 +2911,7 @@ void ED_region_cache_draw_curfra_label(const int framenr, const float x, const f
BLF_width_and_height(fontid, numstr, sizeof(numstr), &font_dims[0], &font_dims[1]);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_CFRAME);
immRecti(pos, x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f);
@@ -2911,7 +2925,7 @@ void ED_region_cache_draw_curfra_label(const int framenr, const float x, const f
void ED_region_cache_draw_cached_segments(const ARegion *ar, const int num_segments, const int *points, const int sfra, const int efra)
{
if (num_segments) {
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ub(128, 128, 255, 128);
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 6cff82295f0..7fa093106df 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -140,9 +140,9 @@ static int get_cached_work_texture(int *r_w, int *r_h)
static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state)
{
- Gwn_VertFormat *vert_format = immVertexFormat();
- state->pos = GWN_vertformat_attr_add(vert_format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- state->texco = GWN_vertformat_attr_add(vert_format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *vert_format = immVertexFormat();
+ state->pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ state->texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
}
/* To be used before calling immDrawPixelsTex
@@ -297,7 +297,7 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
}
- immBegin(GWN_PRIM_TRI_FAN, 4);
+ immBegin(GPU_PRIM_TRI_FAN, 4);
immAttrib2f(texco, (float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h);
immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom);
@@ -364,7 +364,7 @@ void bglPolygonOffset(float viewdist, float dist)
// glPolygonOffset(-1.0, -1.0);
/* hack below is to mimic polygon offset */
- gpuGetProjectionMatrix(winmat);
+ GPU_matrix_projection_get(winmat);
/* dist is from camera to center point */
@@ -401,7 +401,7 @@ void bglPolygonOffset(float viewdist, float dist)
offset = 0.0;
}
- gpuLoadProjectionMatrix(winmat);
+ GPU_matrix_projection_set(winmat);
}
/* **** Color management helper functions for GLSL display/transform ***** */
@@ -551,28 +551,28 @@ void immDrawBorderCorners(unsigned int pos, const rcti *border, float zoomx, flo
delta_y = min_ff(delta_y, border->ymax - border->ymin);
/* left bottom corner */
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos, border->xmin, border->ymin + delta_y);
immVertex2f(pos, border->xmin, border->ymin);
immVertex2f(pos, border->xmin + delta_x, border->ymin);
immEnd();
/* left top corner */
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos, border->xmin, border->ymax - delta_y);
immVertex2f(pos, border->xmin, border->ymax);
immVertex2f(pos, border->xmin + delta_x, border->ymax);
immEnd();
/* right bottom corner */
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos, border->xmax - delta_x, border->ymin);
immVertex2f(pos, border->xmax, border->ymin);
immVertex2f(pos, border->xmax, border->ymin + delta_y);
immEnd();
/* right top corner */
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos, border->xmax - delta_x, border->ymax);
immVertex2f(pos, border->xmax, border->ymax);
immVertex2f(pos, border->xmax, border->ymax - delta_y);
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 17b1af29010..5a520540301 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -34,6 +34,7 @@
#include "DNA_object_types.h"
#include "DNA_armature_types.h"
+#include "DNA_brush_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_sequence_types.h"
#include "DNA_scene_types.h"
@@ -44,10 +45,13 @@
#include "BLI_utildefines.h"
+#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_object.h"
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "BKE_paint.h"
+#include "BKE_main.h"
#include "BKE_gpencil.h"
#include "BKE_layer.h"
#include "BKE_screen.h"
@@ -80,8 +84,7 @@ const char *screen_context_dir[] = {
"sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */
"gpencil_data", "gpencil_data_owner", /* grease pencil data */
"visible_gpencil_layers", "editable_gpencil_layers", "editable_gpencil_strokes",
- "active_gpencil_layer", "active_gpencil_frame", "active_gpencil_palette",
- "active_gpencil_palettecolor", "active_gpencil_brush",
+ "active_gpencil_layer", "active_gpencil_frame", "active_gpencil_brush",
"active_operator", "selected_editable_fcurves",
NULL};
@@ -164,7 +167,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "selectable_bases")) {
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if ((base->flag & BASE_SELECTABLE) != 0) {
+ if ((base->flag & BASE_VISIBLE) && (base->flag & BASE_SELECTABLE) != 0) {
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
@@ -467,7 +470,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
* (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when
* called from context. For that reason, we end up using an alternative where we pass everything in!
*/
- bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact);
if (gpd) {
CTX_data_id_pointer_set(result, &gpd->id);
@@ -482,7 +485,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
PointerRNA ptr;
/* get pointer to Grease Pencil Data */
- gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, scene, sa, obact, &ptr);
+ gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, sa, scene, obact, &ptr);
if (gpd_ptr) {
CTX_data_pointer_set(result, ptr.id.data, ptr.type, ptr.data);
@@ -491,7 +494,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "active_gpencil_layer")) {
/* XXX: see comment for gpencil_data case... */
- bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact);
if (gpd) {
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
@@ -502,47 +505,17 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
}
}
- else if (CTX_data_equals(member, "active_gpencil_palette")) {
- /* XXX: see comment for gpencil_data case... */
- bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
- if (gpd) {
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
-
- if (palette) {
- CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilPalette, palette);
- return 1;
- }
- }
- }
- else if (CTX_data_equals(member, "active_gpencil_palettecolor")) {
- /* XXX: see comment for gpencil_data case... */
- bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
- if (gpd) {
- bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
-
- if (palette) {
- bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette);
- if (palcolor) {
- CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilPaletteColor, palcolor);
- return 1;
- }
- }
- }
- }
else if (CTX_data_equals(member, "active_gpencil_brush")) {
- /* XXX: see comment for gpencil_data case... */
- bGPDbrush *brush = BKE_gpencil_brush_getactive(scene->toolsettings);
+ Brush *brush = BKE_brush_getactive_gpencil(scene->toolsettings);
if (brush) {
- CTX_data_pointer_set(result, &scene->id, &RNA_GPencilBrush, brush);
+ CTX_data_pointer_set(result, &scene->id, &RNA_Brush, brush);
return 1;
}
}
else if (CTX_data_equals(member, "active_gpencil_frame")) {
/* XXX: see comment for gpencil_data case... */
- bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact);
if (gpd) {
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
@@ -555,7 +528,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "visible_gpencil_layers")) {
/* XXX: see comment for gpencil_data case... */
- bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact);
if (gpd) {
bGPDlayer *gpl;
@@ -571,7 +544,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "editable_gpencil_layers")) {
/* XXX: see comment for gpencil_data case... */
- bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact);
if (gpd) {
bGPDlayer *gpl;
@@ -587,24 +560,37 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "editable_gpencil_strokes")) {
/* XXX: see comment for gpencil_data case... */
- bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact);
+ bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
if (gpd) {
bGPDlayer *gpl;
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpencil_layer_is_editable(gpl) && (gpl->actframe)) {
- bGPDframe *gpf = gpl->actframe;
+ bGPDframe *gpf;
bGPDstroke *gps;
+ bGPDframe *init_gpf = gpl->actframe;
+ if (is_multiedit) {
+ init_gpf = gpl->frames.first;
+ }
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
- if (ED_gpencil_stroke_can_use_direct(sa, gps)) {
- /* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
- continue;
+ for (gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ if (ED_gpencil_stroke_can_use_direct(sa, gps)) {
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ continue;
+ }
+
+ CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps);
+ }
}
-
- CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps);
+ }
+ /* if not multiedit out of loop */
+ if (!is_multiedit) {
+ break;
}
}
}
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index 9c46938a90f..10d72d74b22 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -99,7 +99,7 @@ static void draw_horizontal_join_shape(ScrArea *sa, char dir, unsigned int pos)
}
}
- immBegin(GWN_PRIM_TRI_FAN, 5);
+ immBegin(GPU_PRIM_TRI_FAN, 5);
for (i = 0; i < 5; i++) {
immVertex2f(pos, points[i].x, points[i].y);
@@ -107,7 +107,7 @@ static void draw_horizontal_join_shape(ScrArea *sa, char dir, unsigned int pos)
immEnd();
- immBegin(GWN_PRIM_TRI_FAN, 5);
+ immBegin(GPU_PRIM_TRI_FAN, 5);
for (i = 4; i < 8; i++) {
immVertex2f(pos, points[i].x, points[i].y);
@@ -180,7 +180,7 @@ static void draw_vertical_join_shape(ScrArea *sa, char dir, unsigned int pos)
}
}
- immBegin(GWN_PRIM_TRI_FAN, 5);
+ immBegin(GPU_PRIM_TRI_FAN, 5);
for (i = 0; i < 5; i++) {
immVertex2f(pos, points[i].x, points[i].y);
@@ -188,7 +188,7 @@ static void draw_vertical_join_shape(ScrArea *sa, char dir, unsigned int pos)
immEnd();
- immBegin(GWN_PRIM_TRI_FAN, 5);
+ immBegin(GPU_PRIM_TRI_FAN, 5);
for (i = 4; i < 8; i++) {
immVertex2f(pos, points[i].x, points[i].y);
@@ -323,11 +323,11 @@ static void drawscredge_corner(ScrArea *sa, int sizex, int sizey)
/* Wrap up the corners with a nice embossing. */
rcti rect = sa->totrct;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(color);
- immBeginAtMost(GWN_PRIM_LINES, 8);
+ immBeginAtMost(GPU_PRIM_LINES, 8);
/* Right. */
immVertex2f(pos, rect.xmax, rect.ymax);
@@ -386,7 +386,7 @@ static void drawscredge_area_draw(int sizex, int sizey, short x1, short y1, shor
return;
}
- immBegin(GWN_PRIM_LINES, count);
+ immBegin(GPU_PRIM_LINES, count);
/* right border area */
if (x2 < sizex - 1) {
@@ -439,7 +439,7 @@ void ED_screen_draw_edges(wmWindow *win)
ScrArea *sa;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* Note: first loop only draws if U.pixelsize > 1, skip otherwise */
@@ -477,7 +477,7 @@ void ED_screen_draw_edges(wmWindow *win)
*/
void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2)
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
GPU_line_width(1);
@@ -518,14 +518,14 @@ void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2)
void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac)
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* splitpoint */
GPU_blend(true);
immUniformColor4ub(255, 255, 255, 100);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
if (dir == 'h') {
const float y = (1 - fac) * sa->totrct.ymin + fac * sa->totrct.ymax;
@@ -537,7 +537,7 @@ void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac)
immUniformColor4ub(0, 0, 0, 100);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, sa->totrct.xmin, y + 1);
immVertex2f(pos, sa->totrct.xmax, y + 1);
@@ -555,7 +555,7 @@ void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac)
immUniformColor4ub(0, 0, 0, 100);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, x + 1, sa->totrct.ymin);
immVertex2f(pos, x + 1, sa->totrct.ymax);
@@ -594,7 +594,7 @@ static void screen_preview_draw_areas(const bScreen *screen, const float scale[2
const float ofs_between_areas)
{
const float ofs_h = ofs_between_areas * 0.5f;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(col);
@@ -607,7 +607,7 @@ static void screen_preview_draw_areas(const bScreen *screen, const float scale[2
.ymax = sa->totrct.ymax * scale[1] - ofs_h
};
- immBegin(GWN_PRIM_TRI_FAN, 4);
+ immBegin(GPU_PRIM_TRI_FAN, 4);
immVertex2f(pos, rect.xmin, rect.ymin);
immVertex2f(pos, rect.xmax, rect.ymin);
immVertex2f(pos, rect.xmax, rect.ymax);
@@ -627,14 +627,14 @@ static void screen_preview_draw(const bScreen *screen, int size_x, int size_y)
wmOrtho2(0.0f, size_x, 0.0f, size_y);
/* center */
- gpuPushMatrix();
- gpuLoadIdentity();
- gpuTranslate2f(size_x * (1.0f - asp[0]) * 0.5f, size_y * (1.0f - asp[1]) * 0.5f);
+ GPU_matrix_push();
+ GPU_matrix_identity_set();
+ GPU_matrix_translate_2f(size_x * (1.0f - asp[0]) * 0.5f, size_y * (1.0f - asp[1]) * 0.5f);
screen_preview_scale_get(screen, size_x, size_y, asp, scale);
screen_preview_draw_areas(screen, scale, col, 1.5f);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
/**
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index cd71c07a3c0..9f845bf04ba 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -37,7 +37,7 @@ struct Main;
/* internal exports only */
-#define AZONESPOT (0.6f * U.widget_unit)
+#define AZONESPOT (0.8f * U.widget_unit)
#define AZONEFADEIN (5.0f * U.widget_unit) /* when azone is totally visible */
#define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the azone */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index a837b32b0bb..c8ad2b954a5 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -47,6 +47,7 @@
#include "DNA_gpencil_types.h"
#include "DNA_scene_types.h"
#include "DNA_meta_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_mask_types.h"
#include "DNA_node_types.h"
#include "DNA_workspace_types.h"
@@ -359,6 +360,15 @@ bool ED_operator_editmesh_region_view3d(bContext *C)
return 0;
}
+bool ED_operator_editmesh_auto_smooth(bContext *C)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ if (obedit && obedit->type == OB_MESH && (((Mesh *)(obedit->data))->flag & ME_AUTOSMOOTH)) {
+ return NULL != BKE_editmesh_from_object(obedit);
+ }
+ return 0;
+}
+
bool ED_operator_editarmature(bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
@@ -2608,11 +2618,14 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
/* populate tree with keyframe nodes */
scene_to_keylist(&ads, scene, &keys, NULL);
- gpencil_to_keylist(&ads, scene->gpd, &keys);
if (ob) {
ob_to_keylist(&ads, ob, &keys, NULL);
- gpencil_to_keylist(&ads, ob->gpd, &keys);
+
+ if (ob->type == OB_GPENCIL) {
+ const bool active = !(scene->flag & SCE_KEYS_NO_SELONLY);
+ gpencil_to_keylist(&ads, ob->data, &keys, active);
+ }
}
{
@@ -4813,7 +4826,7 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
}
-static bool open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
if (drag->type == WM_DRAG_PATH) {
if (drag->icon == ICON_FILE_BLEND)
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index afaad3963d5..9c0c59a7160 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -247,7 +247,7 @@ static void screenshot_cancel(bContext *UNUSED(C), wmOperator *op)
screenshot_data_free(op);
}
-static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
+static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@@ -266,7 +266,7 @@ static void screenshot_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
- uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
+ uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
}
static bool screenshot_poll(bContext *C)
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 6b3c358d2ac..997fe1282f9 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -618,19 +618,19 @@ static void paint_draw_tex_overlay(
glDepthFunc(GL_ALWAYS);
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
- gpuPushMatrix();
+ GPU_matrix_push();
/* brush rotation */
- gpuTranslate2f(x, y);
- gpuRotate2D(-RAD2DEGF(primary ? ups->brush_rotation : ups->brush_rotation_sec));
- gpuTranslate2f(-x, -y);
+ GPU_matrix_translate_2f(x, y);
+ GPU_matrix_rotate_2d(-RAD2DEGF(primary ? ups->brush_rotation : ups->brush_rotation_sec));
+ GPU_matrix_translate_2f(-x, -y);
/* scale based on tablet pressure */
if (primary && ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) {
const float scale = ups->size_pressure_value;
- gpuTranslate2f(x, y);
- gpuScale2f(scale, scale);
- gpuTranslate2f(-x, -y);
+ GPU_matrix_translate_2f(x, y);
+ GPU_matrix_scale_2f(scale, scale);
+ GPU_matrix_translate_2f(-x, -y);
}
if (ups->draw_anchored) {
@@ -671,18 +671,18 @@ static void paint_draw_tex_overlay(
quad.xmax = brush->mask_stencil_dimension[0];
quad.ymax = brush->mask_stencil_dimension[1];
}
- gpuPushMatrix();
+ GPU_matrix_push();
if (primary)
- gpuTranslate2fv(brush->stencil_pos);
+ GPU_matrix_translate_2fv(brush->stencil_pos);
else
- gpuTranslate2fv(brush->mask_stencil_pos);
- gpuRotate2D(RAD2DEGF(mtex->rot));
+ GPU_matrix_translate_2fv(brush->mask_stencil_pos);
+ GPU_matrix_rotate_2d(RAD2DEGF(mtex->rot));
}
/* set quad color. Colored overlay does not get blending */
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (col) {
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
@@ -696,7 +696,7 @@ static void paint_draw_tex_overlay(
/* draw textured quad */
immUniform1i("image", GL_TEXTURE0);
- immBegin(GWN_PRIM_TRI_FAN, 4);
+ immBegin(GPU_PRIM_TRI_FAN, 4);
immAttrib2f(texCoord, 0.0f, 0.0f);
immVertex2f(pos, quad.xmin, quad.ymin);
immAttrib2f(texCoord, 1.0f, 0.0f);
@@ -710,7 +710,7 @@ static void paint_draw_tex_overlay(
immUnbindProgram();
if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_VIEW)) {
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
}
@@ -762,16 +762,16 @@ static void paint_draw_cursor_overlay(
/* scale based on tablet pressure */
if (ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) {
do_pop = true;
- gpuPushMatrix();
- gpuLoadIdentity();
- gpuTranslate2fv(center);
- gpuScaleUniform(ups->size_pressure_value);
- gpuTranslate2f(-center[0], -center[1]);
+ GPU_matrix_push();
+ GPU_matrix_identity_set();
+ GPU_matrix_translate_2fv(center);
+ GPU_matrix_scale_1f(ups->size_pressure_value);
+ GPU_matrix_translate_2f(-center[0], -center[1]);
}
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
@@ -782,7 +782,7 @@ static void paint_draw_cursor_overlay(
/* draw textured quad */
immUniform1i("image", 0);
- immBegin(GWN_PRIM_TRI_FAN, 4);
+ immBegin(GPU_PRIM_TRI_FAN, 4);
immAttrib2f(texCoord, 0.0f, 0.0f);
immVertex2f(pos, quad.xmin, quad.ymin);
immAttrib2f(texCoord, 1.0f, 0.0f);
@@ -796,7 +796,7 @@ static void paint_draw_cursor_overlay(
immUnbindProgram();
if (do_pop)
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
@@ -844,7 +844,7 @@ BLI_INLINE void draw_tri_point(
{co[0] + w, co[1] - w},
};
- immBegin(GWN_PRIM_LINE_LOOP, 3);
+ immBegin(GPU_PRIM_LINE_LOOP, 3);
immVertex2fv(pos, tri[0]);
immVertex2fv(pos, tri[1]);
immVertex2fv(pos, tri[2]);
@@ -853,7 +853,7 @@ BLI_INLINE void draw_tri_point(
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
GPU_line_width(1.0f);
- immBegin(GWN_PRIM_LINE_LOOP, 3);
+ immBegin(GPU_PRIM_LINE_LOOP, 3);
immVertex2fv(pos, tri[0]);
immVertex2fv(pos, tri[1]);
immVertex2fv(pos, tri[2]);
@@ -888,7 +888,7 @@ BLI_INLINE void draw_bezier_handle_lines(unsigned int pos, float sel_col[4], Bez
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
GPU_line_width(3.0f);
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2fv(pos, bez->vec[0]);
immVertex2fv(pos, bez->vec[1]);
immVertex2fv(pos, bez->vec[2]);
@@ -902,7 +902,7 @@ BLI_INLINE void draw_bezier_handle_lines(unsigned int pos, float sel_col[4], Bez
else {
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
}
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2fv(pos, bez->vec[0]);
immVertex2fv(pos, bez->vec[1]);
immEnd();
@@ -913,7 +913,7 @@ BLI_INLINE void draw_bezier_handle_lines(unsigned int pos, float sel_col[4], Bez
else {
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
}
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2fv(pos, bez->vec[1]);
immVertex2fv(pos, bez->vec[2]);
immEnd();
@@ -930,7 +930,7 @@ static void paint_draw_curve_cursor(Brush *brush)
GPU_blend(true);
/* draw the bezier handles and the curve segment between the current and next point */
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -961,7 +961,7 @@ static void paint_draw_curve_cursor(Brush *brush)
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
GPU_line_width(3.0f);
- immBegin(GWN_PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1);
+ immBegin(GPU_PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1);
for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) {
immVertex2fv(pos, v[j]);
}
@@ -969,7 +969,7 @@ static void paint_draw_curve_cursor(Brush *brush)
immUniformColor4f(0.9f, 0.9f, 1.0f, 0.5f);
GPU_line_width(1.0f);
- immBegin(GWN_PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1);
+ immBegin(GPU_PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1);
for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) {
immVertex2fv(pos, v[j]);
}
@@ -1118,7 +1118,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
GPU_blend(true); /* TODO: also set blend mode? */
GPU_line_smooth(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* set brush color */
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 6276a2838f5..897a74eb497 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -419,15 +419,15 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda
GPU_line_smooth(true);
GPU_blend(true);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
GPU_line_width(4.0);
immUniformColor4ub(0, 0, 0, 255);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2i(pos, x, y);
immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]);
immEnd();
@@ -435,7 +435,7 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda
GPU_line_width(2.0);
immUniformColor4ub(255, 255, 255, 255);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2i(pos, x, y);
immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]);
immEnd();
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 04329697b54..7badd30e6d0 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -5442,7 +5442,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
if (h > maxsize) h = maxsize;
ibuf = ED_view3d_draw_offscreen_imbuf(
- depsgraph, scene, v3d->drawtype,
+ depsgraph, scene, v3d->shading.type,
v3d, CTX_wm_region(C),
w, h, IB_rect, V3D_OFSDRAW_NONE, R_ALPHAPREMUL, 0, NULL,
NULL, err_out);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 0f796020d9e..86d36ade477 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -29,20 +29,27 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLI_math_vector.h"
+#include "BLI_math_color.h"
#include "DNA_customdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_brush_types.h"
+#include "DNA_gpencil_types.h"
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_paint.h"
+#include "BKE_gpencil.h"
#include "BKE_main.h"
+#include "BKE_report.h"
+
+#include "DEG_depsgraph.h"
#include "ED_paint.h"
#include "ED_screen.h"
#include "ED_image.h"
+#include "ED_gpencil.h"
#include "UI_resources.h"
#include "WM_api.h"
@@ -96,6 +103,43 @@ static void BRUSH_OT_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+static int brush_add_gpencil_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ /*int type = RNA_enum_get(op->ptr, "type");*/
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Paint *paint = &ts->gp_paint->paint;
+ Brush *br = BKE_paint_brush(paint);
+ Main *bmain = CTX_data_main(C);
+ // ePaintMode mode = ePaintGpencil;
+
+ if (br) {
+ br = BKE_brush_copy(bmain, br);
+ }
+ else {
+ br = BKE_brush_add(bmain, "Brush", OB_MODE_GPENCIL_PAINT);
+ id_us_min(&br->id); /* fake user only */
+ }
+
+ BKE_paint_brush_set(paint, br);
+
+ /* TODO init grease pencil specific data */
+
+ return OPERATOR_FINISHED;
+}
+
+static void BRUSH_OT_add_gpencil(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Drawing Brush";
+ ot->description = "Add brush for grease pencil";
+ ot->idname = "BRUSH_OT_add_gpencil";
+
+ /* api callbacks */
+ ot->exec = brush_add_gpencil_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
static int brush_scale_size_exec(bContext *C, wmOperator *op)
{
@@ -232,7 +276,6 @@ static void PALETTE_OT_color_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
static int palette_color_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
Paint *paint = BKE_paint_get_active_from_context(C);
@@ -1031,6 +1074,7 @@ void ED_operatortypes_paint(void)
/* brush */
WM_operatortype_append(BRUSH_OT_add);
+ WM_operatortype_append(BRUSH_OT_add_gpencil);
WM_operatortype_append(BRUSH_OT_scale_size);
WM_operatortype_append(BRUSH_OT_curve_preset);
WM_operatortype_append(BRUSH_OT_reset);
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 0ef25eb63a1..fc008213ae0 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -155,11 +155,11 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata
ARegion *ar = stroke->vc.ar;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ubv(paint->paint_cursor_col);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, x, y);
immVertex2f(pos,
stroke->last_mouse_position[0] + ar->winrct.xmin,
@@ -181,7 +181,7 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata)
GPU_line_smooth(true);
- uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -194,7 +194,7 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata)
immUniformArray4fv("colors", (float *)(float[][4]){{0.0f, 0.0f, 0.0f, alpha}, {1.0f, 1.0f, 1.0f, alpha}}, 2);
immUniform1f("dash_width", 6.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
ARegion *ar = stroke->vc.ar;
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 697ffc32759..e914a24092e 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -299,8 +299,8 @@ static void imapaint_pick_uv(Mesh *me_eval, Scene *scene, Object *ob_eval, unsig
/* get the needed opengl matrices */
GPU_viewport_size_get_i(view);
- gpuGetModelViewMatrix(matrix);
- gpuGetProjectionMatrix(proj);
+ GPU_matrix_model_view_get(matrix);
+ GPU_matrix_projection_get(proj);
view[0] = view[1] = 0;
mul_m4_m4m4(matrix, matrix, ob_eval->obmat);
mul_m4_m4m4(matrix, proj, matrix);
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index a0ef753e200..8fafc545fa9 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -215,7 +215,7 @@ static void brush_drawcursor_uvsculpt(bContext *C, int x, int y, void *UNUSED(cu
alpha *= (size - PX_SIZE_FADE_MIN) / (PX_SIZE_FADE_MAX - PX_SIZE_FADE_MIN);
}
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3fvAlpha(brush->add_col, alpha);
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 3fc68a50057..15f688549a8 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -482,7 +482,7 @@ static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *even
#ifdef WITH_AUDASPACE
-static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
+static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
return !(STREQ(prop_id, "filepath") ||
@@ -635,7 +635,7 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op)
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
/* main draw call */
- uiDefAutoButsRNA(layout, &ptr, sound_mixdown_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
+ uiDefAutoButsRNA(layout, &ptr, sound_mixdown_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
}
#endif // WITH_AUDASPACE
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 8e521c997fd..e679688f887 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -211,8 +211,8 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
/* first backdrop strips */
y = (float)(-ACHANNEL_HEIGHT(ac));
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -326,7 +326,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
if (saction->flag & SACTION_MOVING) {
immUniformColor3f(0.0f, 0.0f, 0.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, saction->timeslide, v2d->cur.ymin - EXTRA_SCROLL_PAD);
immVertex2f(pos, saction->timeslide, v2d->cur.ymax);
immEnd();
@@ -404,7 +404,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* iterate over pointcaches on the active object, and draw each one's range */
@@ -436,9 +436,9 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
if (pid->cache->cached_frames == NULL)
continue;
- gpuPushMatrix();
- gpuTranslate2f(0.0, (float)V2D_SCROLL_HEIGHT_TEXT + yoffs);
- gpuScale2f(1.0, cache_draw_height);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(0.0, (float)V2D_SCROLL_HEIGHT_TEXT + yoffs);
+ GPU_matrix_scale_2f(1.0, cache_draw_height);
switch (pid->type) {
case PTCACHE_TYPE_SOFTBODY:
@@ -492,7 +492,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
immUniformColor4fv(col);
if (len > 0) {
- immBeginAtMost(GWN_PRIM_TRIS, len);
+ immBeginAtMost(GPU_PRIM_TRIS, len);
/* draw a quad for each cached frame */
for (int i = sta; i <= end; i++) {
@@ -512,7 +512,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
GPU_blend(false);
- gpuPopMatrix();
+ GPU_matrix_pop();
yoffs += cache_draw_height;
}
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index c46d0fdb035..831c461538a 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -51,6 +51,7 @@
#include "BKE_fcurve.h"
#include "BKE_nla.h"
#include "BKE_context.h"
+#include "BKE_gpencil.h"
#include "UI_view2d.h"
@@ -134,15 +135,20 @@ 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)
+ if (ale->type == ANIMTYPE_GPLAYER) {
ED_gplayer_frame_select_set(ale->data, sel);
- else if (ale->type == ANIMTYPE_MASKLAYER)
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_masklayer_frame_select_set(ale->data, sel);
- else
+ }
+ else {
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL);
+ }
}
/* Cleanup */
+ ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
@@ -283,12 +289,16 @@ static void borderselect_action(bAnimContext *ac, const rcti rect, short mode, s
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
ED_gplayer_frames_select_border(gpl, rectf.xmin, rectf.xmax, selectmode);
}
+ ale->update |= ANIM_UPDATE_DEPS;
break;
}
#endif
case ANIMTYPE_GPLAYER:
+ {
ED_gplayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode);
+ ale->update |= ANIM_UPDATE_DEPS;
break;
+ }
case ANIMTYPE_MASKDATABLOCK:
{
Mask *mask = ale->data;
@@ -312,6 +322,7 @@ static void borderselect_action(bAnimContext *ac, const rcti rect, short mode, s
}
/* cleanup */
+ ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
@@ -493,6 +504,7 @@ static void region_select_action_keys(bAnimContext *ac, const rctf *rectf_view,
case ANIMTYPE_GPLAYER:
{
ED_gplayer_frames_select_region(&ked, ale->data, mode, selectmode);
+ ale->update |= ANIM_UPDATE_DEPS;
break;
}
case ANIMTYPE_MASKDATABLOCK:
@@ -520,6 +532,7 @@ static void region_select_action_keys(bAnimContext *ac, const rctf *rectf_view,
}
/* cleanup */
+ ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
@@ -707,6 +720,7 @@ static void markers_selectkeys_between(bAnimContext *ac)
}
else if (ale->type == ANIMTYPE_GPLAYER) {
ED_gplayer_frames_select_border(ale->data, min, max, SELECT_ADD);
+ ale->update |= ANIM_UPDATE_DEPS;
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_masklayer_frames_select_border(ale->data, min, max, SELECT_ADD);
@@ -717,6 +731,7 @@ static void markers_selectkeys_between(bAnimContext *ac)
}
/* Cleanup */
+ ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
@@ -796,17 +811,23 @@ static void columnselect_action_keys(bAnimContext *ac, short mode)
ked.f1 = ce->cfra;
/* select elements with frame number matching cfraelem */
- if (ale->type == ANIMTYPE_GPLAYER)
+ if (ale->type == ANIMTYPE_GPLAYER) {
ED_gpencil_select_frame(ale->data, ce->cfra, SELECT_ADD);
- else if (ale->type == ANIMTYPE_MASKLAYER)
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_mask_select_frame(ale->data, ce->cfra, SELECT_ADD);
- else
+ }
+ else {
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
}
}
/* free elements */
BLI_freelistN(&ked.list);
+
+ ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
@@ -1081,12 +1102,16 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
}
- else if (ale->type == ANIMTYPE_GPLAYER)
+ else if (ale->type == ANIMTYPE_GPLAYER) {
ED_gplayer_frames_select_border(ale->data, ked.f1, ked.f2, select_mode);
- else if (ale->type == ANIMTYPE_MASKLAYER)
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_masklayer_frames_select_border(ale->data, ked.f1, ked.f2, select_mode);
- else
+ }
+ else {
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
}
/* Sync marker support */
@@ -1111,6 +1136,7 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se
}
/* Cleanup */
+ ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
@@ -1227,6 +1253,7 @@ static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short s
/* select the nominated keyframe on the given frame */
if (ale->type == ANIMTYPE_GPLAYER) {
ED_gpencil_select_frame(ale->data, selx, select_mode);
+ ale->update |= ANIM_UPDATE_DEPS;
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_mask_select_frame(ale->data, selx, select_mode);
@@ -1244,12 +1271,14 @@ static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short s
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_GPLAYER) {
ED_gpencil_select_frame(ale->data, selx, select_mode);
+ ale->update |= ANIM_UPDATE_DEPS;
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_mask_select_frame(ale->data, selx, select_mode);
}
}
+ ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
else {
@@ -1294,16 +1323,22 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se
ked.f1 = selx;
/* select elements with frame number matching cfra */
- if (ale->type == ANIMTYPE_GPLAYER)
+ if (ale->type == ANIMTYPE_GPLAYER) {
ED_gpencil_select_frame(ale->key_data, selx, select_mode);
- else if (ale->type == ANIMTYPE_MASKLAYER)
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_mask_select_frame(ale->key_data, selx, select_mode);
- else
+ }
+ else {
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
}
/* free elements */
BLI_freelistN(&ked.list);
+
+ ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
@@ -1318,6 +1353,7 @@ static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, s
/* select all keyframes in this channel */
if (ale->type == ANIMTYPE_GPLAYER) {
ED_gpencil_select_frames(ale->data, select_mode);
+ ale->update = ANIM_UPDATE_DEPS;
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_mask_select_frames(ale->data, select_mode);
@@ -1335,12 +1371,14 @@ static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, s
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_GPLAYER) {
ED_gpencil_select_frames(ale->data, select_mode);
+ ale->update |= ANIM_UPDATE_DEPS;
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_mask_select_frames(ale->data, select_mode);
}
}
+ ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
else {
@@ -1473,6 +1511,7 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_
/* remove active channel from list of channels for separate treatment (since it's needed later on) */
BLI_remlink(&anim_data, ale);
+ ale->next = ale->prev = NULL;
/* cleanup temporary lists */
BLI_dlrbTree_free(&anim_keys);
@@ -1557,6 +1596,12 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_
}
}
+ /* flush tagged updates
+ * NOTE: We temporarily add this channel back to the list so that this can happen
+ */
+ anim_data.first = anim_data.last = ale;
+ ANIM_animdata_update(ac, &anim_data);
+
/* free this channel */
MEM_freeN(ale);
}
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 7246812dc82..84de55a172d 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -136,6 +136,7 @@ void ED_spacetypes_init(void)
ED_gizmotypes_arrow_2d();
ED_gizmotypes_arrow_3d();
ED_gizmotypes_primitive_3d();
+ ED_gizmotypes_blank_3d();
ED_gizmotypes_cage_2d();
ED_gizmotypes_cage_3d();
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index faee9c2b7ac..67632f6a53a 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -237,6 +237,7 @@ static int buttons_context_path_data(ButsContextPath *path, int type)
else if (RNA_struct_is_a(ptr->type, &RNA_Light) && (type == -1 || type == OB_LAMP)) return 1;
else if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && (type == -1 || type == OB_SPEAKER)) return 1;
else if (RNA_struct_is_a(ptr->type, &RNA_LightProbe) && (type == -1 || type == OB_LIGHTPROBE)) return 1;
+ else if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) return 1;
/* try to get an object in the path, no pinning supported here */
else if (buttons_context_path_object(path)) {
ob = path->ptr[path->len - 1].data;
@@ -260,7 +261,21 @@ static int buttons_context_path_modifier(ButsContextPath *path)
if (buttons_context_path_object(path)) {
ob = path->ptr[path->len - 1].data;
- if (ob && ELEM(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_LATTICE))
+ if (ob && ELEM(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_LATTICE, OB_GPENCIL))
+ return 1;
+ }
+
+ return 0;
+}
+
+static int buttons_context_path_shaderfx(ButsContextPath *path)
+{
+ Object *ob;
+
+ if (buttons_context_path_object(path)) {
+ ob = path->ptr[path->len - 1].data;
+
+ if (ob && ELEM(ob->type, OB_GPENCIL))
return 1;
}
@@ -485,6 +500,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
WorkSpace *workspace = CTX_wm_workspace(C);
ID *id;
int found;
+ Object *ob = CTX_data_active_object(C);
memset(path, 0, sizeof(*path));
path->flag = flag;
@@ -546,6 +562,9 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
case BCONTEXT_MODIFIER:
found = buttons_context_path_modifier(path);
break;
+ case BCONTEXT_SHADERFX:
+ found = buttons_context_path_shaderfx(path);
+ break;
case BCONTEXT_DATA:
found = buttons_context_path_data(path, -1);
break;
@@ -553,7 +572,14 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
found = buttons_context_path_particle(path);
break;
case BCONTEXT_MATERIAL:
- found = buttons_context_path_material(path);
+ /* NOTE: Grease Pencil materials use different panels... */
+ if (ob && ob->type == OB_GPENCIL) {
+ /* XXX: Why path_data? */
+ found = buttons_context_path_data(path, -1);
+ }
+ else {
+ found = buttons_context_path_material(path);
+ }
break;
case BCONTEXT_TEXTURE:
found = buttons_context_path_texture(C, path, sbuts->texuser);
@@ -626,10 +652,18 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts)
if (a == BCONTEXT_DATA) {
ptr = &path->ptr[path->len - 1];
- if (ptr->type)
+ if (ptr->type) {
sbuts->dataicon = RNA_struct_ui_icon(ptr->type);
- else
- sbuts->dataicon = ICON_EMPTY_DATA;
+ }
+ else {
+ Object *ob = CTX_data_active_object(C);
+ if (ob->type == OB_GPENCIL) {
+ sbuts->dataicon = ICON_GREASEPENCIL;
+ }
+ else {
+ sbuts->dataicon = ICON_EMPTY_DATA;
+ }
+ }
}
}
}
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 66684de18ac..de422565abd 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -55,6 +55,7 @@
#include "BKE_layer.h"
#include "BKE_linestyle.h"
#include "BKE_modifier.h"
+#include "BKE_gpencil_modifier.h"
#include "BKE_node.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
@@ -152,6 +153,19 @@ static void buttons_texture_modifier_foreach(void *userData, Object *ob, Modifie
N_("Modifiers"), RNA_struct_ui_icon(ptr.type), md->name);
}
+static void buttons_texture_modifier_gpencil_foreach(void *userData, Object *ob, GpencilModifierData *md, const char *propname)
+{
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ ListBase *users = userData;
+
+ RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, &ptr);
+ prop = RNA_struct_find_property(&ptr, propname);
+
+ buttons_texture_user_property_add(users, &ob->id, ptr, prop,
+ N_("Grease Pencil Modifiers"), RNA_struct_ui_icon(ptr.type), md->name);
+}
+
static void buttons_texture_users_from_context(ListBase *users, const bContext *C, SpaceButs *sbuts)
{
Scene *scene = NULL;
@@ -203,6 +217,9 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
/* modifiers */
modifiers_foreachTexLink(ob, buttons_texture_modifier_foreach, users);
+ /* grease pencil modifiers */
+ BKE_gpencil_modifiers_foreachTexLink(ob, buttons_texture_modifier_gpencil_foreach, users);
+
/* particle systems */
if (psys && !limited_mode) {
for (a = 0; a < MAX_MTEX; a++) {
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 6f7a4ca971a..0350e3fcd14 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -180,6 +180,9 @@ static void buttons_main_region_layout_properties(const bContext *C, SpaceButs *
case BCONTEXT_MODIFIER:
contexts[0] = "modifier";
break;
+ case BCONTEXT_SHADERFX:
+ contexts[0] = "shaderfx";
+ break;
case BCONTEXT_CONSTRAINT:
contexts[0] = "constraint";
break;
@@ -200,8 +203,9 @@ static void buttons_main_region_layout_tool(const bContext *C, ARegion *ar)
const char *contexts[3] = {NULL};
const WorkSpace *workspace = CTX_wm_workspace(C);
+ const int mode = CTX_data_mode_enum(C);
+
if (workspace->tools_space_type == SPACE_VIEW3D) {
- const int mode = CTX_data_mode_enum(C);
switch (mode) {
case CTX_MODE_EDIT_MESH:
ARRAY_SET_ITEMS(contexts, ".mesh_edit");
@@ -240,17 +244,44 @@ static void buttons_main_region_layout_tool(const bContext *C, ARegion *ar)
ARRAY_SET_ITEMS(contexts, ".paint_common", ".imagepaint");
break;
case CTX_MODE_PARTICLE:
- ARRAY_SET_ITEMS(contexts, ".particlemode");
+ ARRAY_SET_ITEMS(contexts, ".paint_common", ".particlemode");
break;
case CTX_MODE_OBJECT:
ARRAY_SET_ITEMS(contexts, ".objectmode");
break;
+ case CTX_MODE_GPENCIL_PAINT:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_paint");
+ break;
+ case CTX_MODE_GPENCIL_SCULPT:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_sculpt");
+ break;
+ case CTX_MODE_GPENCIL_WEIGHT:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_weight");
+ break;
}
}
else if (workspace->tools_space_type == SPACE_IMAGE) {
/* TODO */
}
+ /* for grease pencil we don't use tool system yet, so we need check outside
+ * workspace->tools_space_type because this value is not available
+ */
+ switch (mode) {
+ case CTX_MODE_GPENCIL_PAINT:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_paint");
+ break;
+ case CTX_MODE_GPENCIL_SCULPT:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_sculpt");
+ break;
+ case CTX_MODE_GPENCIL_WEIGHT:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_weight");
+ break;
+ case CTX_MODE_GPENCIL_EDIT:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_edit");
+ break;
+ }
+
const bool vertical = true;
ED_region_panels_layout_ex(C, ar, contexts, -1, vertical);
}
@@ -495,6 +526,14 @@ static void buttons_area_listener(
break;
}
break;
+ case NC_GPENCIL:
+ switch (wmn->data) {
+ case ND_DATA:
+ if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED))
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ break;
case NC_NODE:
if (wmn->action == NA_SELECTED) {
ED_area_tag_redraw(sa);
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index db5f6c2451c..6953b7cfb71 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -107,7 +107,7 @@ void uiTemplateMovieClip(uiLayout *layout, bContext *C, PointerRNA *ptr, const c
uiLayoutSetContextPointer(layout, "edit_movieclip", &clipptr);
if (!compact)
- uiTemplateID(layout, C, ptr, propname, NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, propname, NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
if (clip) {
uiLayout *col;
diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c
index 76450cba3cb..2aa0a3e2b9a 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_draw.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c
@@ -130,8 +130,8 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
uint keyframe_len = 0;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* don't use totrect set, as the width stays the same
@@ -215,14 +215,14 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
if (keyframe_len > 0) {
/* draw keyframe markers */
format = immVertexFormat();
- pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint size_id = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT);
- uint color_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
- uint outline_color_id = GWN_vertformat_attr_add(format, "outlineColor", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
GPU_enable_program_point_size();
- immBegin(GWN_PRIM_POINTS, keyframe_len);
+ immBegin(GPU_PRIM_POINTS, keyframe_len);
/* all same size with black outline */
immAttrib1f(size_id, 2.0f * STRIP_HEIGHT_HALF);
@@ -315,8 +315,8 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
*/
float y = (float) CHANNEL_FIRST;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 164565192fd..ebdf5342172 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -80,7 +80,7 @@ static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int wid
int x = (frame - sfra) * framelen;
if (width == 1) {
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2i(pos, x, 0);
immVertex2i(pos, x, height * UI_DPI_FAC);
immEnd();
@@ -167,7 +167,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
ED_region_cache_draw_cached_segments(ar, totseg, points, sfra, efra);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* track */
@@ -248,7 +248,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
ED_region_cache_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC);
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* solver keyframes */
@@ -290,7 +290,7 @@ static void draw_movieclip_muted(ARegion *ar, int width, int height, float zoomx
{
int x, y;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* find window pixel coordinates of origin */
@@ -349,18 +349,18 @@ static void draw_stabilization_border(SpaceClip *sc, ARegion *ar, int width, int
/* draw boundary border for frame if stabilization is enabled */
if (sc->flag & SC_SHOW_STABLE && clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
/* Exclusive OR allows to get orig value when second operand is 0,
* and negative of orig value when second operand is 1. */
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(GL_XOR);
- gpuPushMatrix();
- gpuTranslate2f(x, y);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(x, y);
- gpuScale2f(zoomx, zoomy);
- gpuMultMatrix(sc->stabmat);
+ GPU_matrix_scale_2f(zoomx, zoomy);
+ GPU_matrix_mul(sc->stabmat);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -377,7 +377,7 @@ static void draw_stabilization_border(SpaceClip *sc, ARegion *ar, int width, int
immUnbindProgram();
- gpuPopMatrix();
+ GPU_matrix_pop();
glDisable(GL_COLOR_LOGIC_OP);
}
@@ -452,7 +452,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin
i++;
}
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -463,7 +463,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin
if ((b - a - 1) >= 1) {
GPU_point_size(5.0f);
- immBegin(GWN_PRIM_POINTS, b - a - 1);
+ immBegin(GPU_PRIM_POINTS, b - a - 1);
for (i = a; i < b; i++) {
if (i != curindex) {
@@ -478,7 +478,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin
if ((b - a) >= 2) {
GPU_line_width(3.0f);
- immBegin(GWN_PRIM_LINE_STRIP, b - a);
+ immBegin(GPU_PRIM_LINE_STRIP, b - a);
for (i = a; i < b; i++) {
immVertex2f(pos, path[i][0], path[i][1]);
@@ -494,7 +494,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin
if ((curindex - a) >= 1) {
immUniformThemeColor(TH_PATH_BEFORE);
- immBegin(GWN_PRIM_POINTS, curindex - a);
+ immBegin(GPU_PRIM_POINTS, curindex - a);
for (i = a; i < curindex; i++) {
immVertex2f(pos, path[i][0], path[i][1]);
@@ -506,7 +506,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin
if ((b - curindex - 1) >= 1) {
immUniformThemeColor(TH_PATH_AFTER);
- immBegin(GWN_PRIM_POINTS, b - curindex - 1);
+ immBegin(GPU_PRIM_POINTS, b - curindex - 1);
for (i = curindex + 1; i < b; i++) {
immVertex2f(pos, path[i][0], path[i][1]);
@@ -521,7 +521,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin
if ((curindex - a + 1) >= 2) {
immUniformThemeColor(TH_PATH_BEFORE);
- immBegin(GWN_PRIM_LINE_STRIP, curindex - a + 1);
+ immBegin(GPU_PRIM_LINE_STRIP, curindex - a + 1);
for (i = a; i <= curindex; i++) {
immVertex2f(pos, path[i][0], path[i][1]);
@@ -533,7 +533,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin
if ((b - curindex) >= 2) {
immUniformThemeColor(TH_PATH_AFTER);
- immBegin(GWN_PRIM_LINE_STRIP, b - curindex);
+ immBegin(GPU_PRIM_LINE_STRIP, b - curindex);
for (i = curindex; i < b; i++) {
immVertex2f(pos, path[i][0], path[i][1]);
@@ -579,12 +579,12 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT
{
GPU_point_size(tiny ? 3.0f : 4.0f);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex2f(position, pos[0], pos[1]);
immEnd();
}
else {
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
immVertex2f(position, pos[0] + px[0] * 2, pos[1]);
immVertex2f(position, pos[0] + px[0] * 8, pos[1]);
@@ -603,11 +603,11 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT
}
/* pattern and search outline */
- gpuPushMatrix();
- gpuTranslate2fv(marker_pos);
+ GPU_matrix_push();
+ GPU_matrix_translate_2fv(marker_pos);
if (sc->flag & SC_SHOW_MARKER_PATTERN) {
- immBegin(GWN_PRIM_LINE_LOOP, 4);
+ immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex2fv(position, marker->pattern_corners[0]);
immVertex2fv(position, marker->pattern_corners[1]);
immVertex2fv(position, marker->pattern_corners[2]);
@@ -625,7 +625,7 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT
marker->search_max[1]);
}
- gpuPopMatrix();
+ GPU_matrix_pop();
}
static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3])
@@ -705,14 +705,14 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
immUniform1f("dash_factor", 2.0f); /* Solid "line" */
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex2f(shdr_pos, pos[0], pos[1]);
immEnd();
}
else {
immUniform1f("dash_factor", 2.0f); /* Solid line */
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
immVertex2f(shdr_pos, pos[0] + px[0] * 3, pos[1]);
immVertex2f(shdr_pos, pos[0] + px[0] * 7, pos[1]);
@@ -735,7 +735,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(GL_XOR);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2fv(shdr_pos, pos);
immVertex2fv(shdr_pos, marker_pos);
immEnd();
@@ -745,8 +745,8 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
}
/* pattern */
- gpuPushMatrix();
- gpuTranslate2fv(marker_pos);
+ GPU_matrix_push();
+ GPU_matrix_translate_2fv(marker_pos);
if (track->flag & TRACK_LOCKED) {
if (act) {
@@ -783,7 +783,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
}
if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) {
- immBegin(GWN_PRIM_LINE_LOOP, 4);
+ immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex2fv(shdr_pos, marker->pattern_corners[0]);
immVertex2fv(shdr_pos, marker->pattern_corners[1]);
immVertex2fv(shdr_pos, marker->pattern_corners[2]);
@@ -800,12 +800,12 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
marker->search_max[0], marker->search_max[1]);
}
- gpuPopMatrix();
+ GPU_matrix_pop();
/* Restore default shader */
immUnbindProgram();
- const uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
BLI_assert(pos == shdr_pos);
UNUSED_VARS_NDEBUG(pos);
@@ -857,7 +857,7 @@ static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int
tdy += px[1];
}
- immBegin(GWN_PRIM_TRIS, 3);
+ immBegin(GPU_PRIM_TRIS, 3);
immVertex2f(pos, x, y);
immVertex2f(pos, x - tdx, y);
immVertex2f(pos, x, y + tdy);
@@ -884,8 +884,8 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo
immUniformThemeColor(TH_MARKER_OUTLINE);
}
- gpuPushMatrix();
- gpuTranslate2fv(marker_pos);
+ GPU_matrix_push();
+ GPU_matrix_translate_2fv(marker_pos);
dx = 6.0f / width / sc->zoom;
dy = 6.0f / height / sc->zoom;
@@ -935,7 +935,7 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo
GPU_line_width(outline ? 3.0f : 1.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, 0.0f, 0.0f);
immVertex2fv(pos, tilt_ctrl);
immEnd();
@@ -944,7 +944,7 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo
draw_marker_slide_square(tilt_ctrl[0], tilt_ctrl[1], patdx, patdy, outline, px, pos);
}
- gpuPopMatrix();
+ GPU_matrix_pop();
}
static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
@@ -1141,18 +1141,18 @@ static void draw_plane_marker_image(Scene *scene,
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA,
GL_UNSIGNED_BYTE, display_buffer);
- gpuPushMatrix();
- gpuMultMatrix(gl_matrix);
+ GPU_matrix_push();
+ GPU_matrix_mul(gl_matrix);
- Gwn_VertFormat *imm_format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(imm_format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint texCoord = GWN_vertformat_attr_add(imm_format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *imm_format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint texCoord = GPU_vertformat_attr_add(imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
immUniformColor4f(1.0f, 1.0f, 1.0f, plane_track->image_opacity);
immUniform1i("image", 0);
- immBegin(GWN_PRIM_TRI_FAN, 4);
+ immBegin(GPU_PRIM_TRI_FAN, 4);
immAttrib2f(texCoord, 0.0f, 0.0f);
immVertex2f(pos, 0.0f, 0.0f);
@@ -1170,7 +1170,7 @@ static void draw_plane_marker_image(Scene *scene,
immUnbindProgram();
- gpuPopMatrix();
+ GPU_matrix_pop();
glBindTexture(GL_TEXTURE_2D, 0);
@@ -1206,7 +1206,7 @@ static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlane
}
if (draw_plane_quad || is_selected_track) {
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -1239,7 +1239,7 @@ static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlane
}
/* Draw rectangle itself. */
- immBegin(GWN_PRIM_LINE_LOOP, 4);
+ immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex2fv(shdr_pos, plane_marker->corners[0]);
immVertex2fv(shdr_pos, plane_marker->corners[1]);
immVertex2fv(shdr_pos, plane_marker->corners[2]);
@@ -1252,7 +1252,7 @@ static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlane
immUniformColor3f(1.0f, 0.0f, 0.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[1], end_point);
immVertex2fv(shdr_pos, plane_marker->corners[0]);
@@ -1262,7 +1262,7 @@ static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlane
immUniformColor3f(0.0f, 1.0f, 0.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[3], end_point);
immVertex2fv(shdr_pos, plane_marker->corners[0]);
@@ -1342,13 +1342,13 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
- gpuPushMatrix();
- gpuTranslate2f(x, y);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(x, y);
- gpuPushMatrix();
- gpuScale2f(zoomx, zoomy);
- gpuMultMatrix(sc->stabmat);
- gpuScale2f(width, height);
+ GPU_matrix_push();
+ GPU_matrix_scale_2f(zoomx, zoomy);
+ GPU_matrix_mul(sc->stabmat);
+ GPU_matrix_scale_2f(width, height);
act_track = BKE_tracking_track_get_active(tracking);
@@ -1414,7 +1414,7 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
}
}
- uint position = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint position = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1519,7 +1519,7 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
immUniformColor3f(1.0f, 0.0f, 0.0f);
}
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
if (undistort) {
immVertex2f(position, pos[0] / width, pos[1] / (height * aspy));
@@ -1539,7 +1539,7 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
immUnbindProgram();
- gpuPopMatrix();
+ GPU_matrix_pop();
if (sc->flag & SC_SHOW_NAMES) {
/* scaling should be cleared before drawing texts, otherwise font would also be scaled */
@@ -1565,7 +1565,7 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
}
}
- gpuPopMatrix();
+ GPU_matrix_pop();
if (marker_pos)
MEM_freeN(marker_pos);
@@ -1592,13 +1592,13 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
- gpuPushMatrix();
- gpuTranslate2f(x, y);
- gpuScale2f(zoomx, zoomy);
- gpuMultMatrix(sc->stabmat);
- gpuScale2f(width, height);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(x, y);
+ GPU_matrix_scale_2f(zoomx, zoomy);
+ GPU_matrix_mul(sc->stabmat);
+ GPU_matrix_scale_2f(width, height);
- uint position = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint position = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1675,7 +1675,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
immUniformColor3f(1.0f, 0.0f, 0.0f);
for (i = 0; i <= n; i++) {
- immBegin(GWN_PRIM_LINE_STRIP, n + 1);
+ immBegin(GPU_PRIM_LINE_STRIP, n + 1);
for (j = 0; j <= n; j++) {
immVertex2fv(position, grid[i][j]);
@@ -1685,7 +1685,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
}
for (j = 0; j <= n; j++) {
- immBegin(GWN_PRIM_LINE_STRIP, n + 1);
+ immBegin(GPU_PRIM_LINE_STRIP, n + 1);
for (i = 0; i <= n; i++) {
immVertex2fv(position, grid[i][j]);
@@ -1743,7 +1743,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
sub_v2_v2v2(dpos, npos, pos);
mul_v2_fl(dpos, 1.0f / steps);
- immBegin(GWN_PRIM_LINE_STRIP, steps + 1);
+ immBegin(GPU_PRIM_LINE_STRIP, steps + 1);
for (j = 0; j <= steps; j++) {
BKE_tracking_distort_v2(tracking, pos, tpos);
@@ -1756,7 +1756,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
}
}
else if (stroke->totpoints == 1) {
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex2f(position, stroke->points[0].x + offsx, stroke->points[0].y + offsy);
immEnd();
}
@@ -1774,7 +1774,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
immUnbindProgram();
- gpuPopMatrix();
+ GPU_matrix_pop();
}
void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar)
@@ -1871,8 +1871,8 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d)
* associated with the clip is already drawn in draw_distortion
*/
if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || is_track_source) {
- gpuPushMatrix();
- gpuMultMatrix(sc->unistabmat);
+ GPU_matrix_push();
+ GPU_matrix_mul(sc->unistabmat);
if (is_track_source) {
MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);
@@ -1881,13 +1881,13 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d)
int framenr = ED_space_clip_get_clip_frame_number(sc);
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
- gpuTranslate2fv(marker->pos);
+ GPU_matrix_translate_2fv(marker->pos);
}
}
ED_gpencil_draw_2dimage(C);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
else {
diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c
index 34720b3a627..cc8541d9fd7 100644
--- a/source/blender/editors/space_clip/clip_graph_draw.c
+++ b/source/blender/editors/space_clip/clip_graph_draw.c
@@ -91,11 +91,11 @@ static void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track,
immUniformColor4fv(col);
if (is_point) {
- immBeginAtMost(GWN_PRIM_POINTS, 1);
+ immBeginAtMost(GPU_PRIM_POINTS, 1);
}
else {
/* Graph can be composed of smaller segments, if any marker is disabled */
- immBeginAtMost(GWN_PRIM_LINE_STRIP, track->markersnr);
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, track->markersnr);
}
}
@@ -119,13 +119,13 @@ static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track,
if (sel == data->sel) {
immUniformThemeColor(sel ? TH_HANDLE_VERTEX_SELECT : TH_HANDLE_VERTEX);
- gpuPushMatrix();
- gpuTranslate2f(scene_framenr, val);
- gpuScale2f(1.0f / data->xscale * data->hsize, 1.0f / data->yscale * data->hsize);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(scene_framenr, val);
+ GPU_matrix_scale_2f(1.0f / data->xscale * data->hsize, 1.0f / data->yscale * data->hsize);
imm_draw_circle_wire_2d(data->pos, 0, 0, 0.7, 8);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
@@ -237,11 +237,11 @@ static void tracking_error_segment_start_cb(void *userdata, MovieTrackingTrack *
immUniformColor4fv(col);
if (is_point) { /* This probably never happens here, but just in case... */
- immBeginAtMost(GWN_PRIM_POINTS, 1);
+ immBeginAtMost(GPU_PRIM_POINTS, 1);
}
else {
/* Graph can be composed of smaller segments, if any marker is disabled */
- immBeginAtMost(GWN_PRIM_LINE_STRIP, track->markersnr);
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, track->markersnr);
}
}
}
@@ -300,7 +300,7 @@ static void draw_frame_curves(SpaceClip *sc, unsigned int pos)
}
if (!lines) {
- immBeginAtMost(GWN_PRIM_LINE_STRIP, reconstruction->camnr);
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, reconstruction->camnr);
lines = 1;
}
@@ -328,7 +328,7 @@ void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene)
UI_view2d_grid_free(grid);
if (clip) {
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
GPU_point_size(3.0f);
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
index c94853d4233..19d321a53bf 100644
--- a/source/blender/editors/space_clip/clip_utils.c
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -273,7 +273,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene)
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
GPU_blend(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f);
@@ -287,7 +287,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene)
/* thin lines where the actual frames are */
GPU_line_width(1.0f);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, (float)SFRA, v2d->cur.ymin);
immVertex2f(pos, (float)SFRA, v2d->cur.ymax);
immVertex2f(pos, (float)EFRA, v2d->cur.ymin);
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 4ac9010d3b5..4f9fd9c65d7 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -236,7 +236,7 @@ static SpaceLink *clip_new(const ScrArea *sa, const Scene *scene)
sc = MEM_callocN(sizeof(SpaceClip), "initclip");
sc->spacetype = SPACE_CLIP;
sc->flag = SC_SHOW_MARKER_PATTERN | SC_SHOW_TRACK_PATH |
- SC_SHOW_GRAPH_TRACKS_MOTION | SC_SHOW_GRAPH_FRAMES | SC_SHOW_GPENCIL;
+ SC_SHOW_GRAPH_TRACKS_MOTION | SC_SHOW_GRAPH_FRAMES | SC_SHOW_ANNOTATION;
sc->zoom = 1.0f;
sc->path_length = 20;
sc->scopes.track_preview_height = 120;
@@ -847,7 +847,7 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul
}
/* dropboxes */
-static bool clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
if (drag->type == WM_DRAG_PATH)
if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */
@@ -1185,18 +1185,18 @@ static void clip_main_region_draw(const bContext *C, ARegion *ar)
show_cursor |= sc->around == V3D_AROUND_CURSOR;
if (show_cursor) {
- gpuPushMatrix();
- gpuTranslate2f(x, y);
- gpuScale2f(zoomx, zoomy);
- gpuMultMatrix(sc->stabmat);
- gpuScale2f(width, height);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(x, y);
+ GPU_matrix_scale_2f(zoomx, zoomy);
+ GPU_matrix_mul(sc->stabmat);
+ GPU_matrix_scale_2f(width, height);
ED_image_draw_cursor(ar, sc->cursor);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
clip_draw_cache_and_notes(C, sc, ar);
- if (sc->flag & SC_SHOW_GPENCIL) {
+ if (sc->flag & SC_SHOW_ANNOTATION) {
/* Grease Pencil */
clip_draw_grease_pencil((bContext *)C, true);
}
@@ -1204,7 +1204,7 @@ static void clip_main_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
- if (sc->flag & SC_SHOW_GPENCIL) {
+ if (sc->flag & SC_SHOW_ANNOTATION) {
/* draw Grease Pencil - screen space only */
clip_draw_grease_pencil((bContext *)C, false);
}
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index 0ffbe451042..789194c21b9 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -158,8 +158,8 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha
int offl = 0, offc = 0;
int xy[2] = {CONSOLE_DRAW_MARGIN, CONSOLE_DRAW_MARGIN};
int pen[2];
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
xy[1] += tvc->lheight / 6;
console_cursor_wrap_offset(sc->prompt, tvc->console_width, &offl, &offc, NULL);
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index 3a48d5ad7dd..3429d726349 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -170,31 +170,24 @@ static void console_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
/* ************* dropboxes ************* */
-static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
-// SpaceConsole *sc = CTX_wm_space_console(C);
- if (drag->type == WM_DRAG_ID)
- return 1;
- return 0;
+ return WM_drag_ID(drag, 0) != NULL;
}
static void id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- char *text;
- ID *id = drag->poin;
+ ID *id = WM_drag_ID(drag, 0);
/* copy drag path to properties */
- text = RNA_path_full_ID_py(id);
+ char *text = RNA_path_full_ID_py(id);
RNA_string_set(drop->ptr, "text", text);
MEM_freeN(text);
}
-static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
- // SpaceConsole *sc = CTX_wm_space_console(C);
- if (drag->type == WM_DRAG_PATH)
- return 1;
- return 0;
+ return (drag->type == WM_DRAG_PATH);
}
static void path_drop_copy(wmDrag *drag, wmDropBox *drop)
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 42ad34b659b..4a71afbcf4a 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -402,8 +402,8 @@ static void file_draw_preview(
/* border */
if (use_dropshadow) {
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f);
@@ -466,7 +466,7 @@ static void draw_background(FileLayout *layout, View2D *v2d)
int i;
int sy;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShade(TH_BACK, -7);
@@ -503,12 +503,12 @@ static void draw_dividers(FileLayout *layout, View2D *v2d)
v1[1] = v2d->cur.ymax - layout->tile_border_y;
v2[1] = v2d->cur.ymin;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GWN_PRIM_LINES, vertex_len);
+ immBegin(GPU_PRIM_LINES, vertex_len);
sx = (int)v2d->tot.xmin;
while (sx < v2d->cur.xmax) {
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
index 812a671ff33..cbf685e6ed8 100644
--- a/source/blender/editors/space_file/file_panels.c
+++ b/source/blender/editors/space_file/file_panels.c
@@ -43,6 +43,7 @@
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
+#include "RNA_define.h"
#include "ED_fileselect.h"
@@ -71,25 +72,33 @@ static void file_panel_operator_header(const bContext *C, Panel *pa)
BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname));
}
-static bool file_panel_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
-{
- const char *prop_id = RNA_property_identifier(prop);
- return !(STREQ(prop_id, "filepath") ||
- STREQ(prop_id, "directory") ||
- STREQ(prop_id, "filename")
- );
-}
-
static void file_panel_operator(const bContext *C, Panel *pa)
{
SpaceFile *sfile = CTX_wm_space_file(C);
wmOperator *op = sfile->op;
- // int empty = 1, flag;
UI_block_func_set(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL);
- uiTemplateOperatorPropertyButs(C, pa->layout, op, file_panel_check_prop, UI_BUT_LABEL_ALIGN_NONE,
- UI_TEMPLATE_OP_PROPS_SHOW_EMPTY);
+ /* Hack: temporary hide.*/
+ const char *hide[] = {"filepath", "files", "directory", "filename"};
+ for (int i = 0; i < ARRAY_SIZE(hide); i++) {
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, hide[i]);
+ if (prop) {
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ }
+ }
+
+ uiTemplateOperatorPropertyButs(
+ C, pa->layout, op, UI_BUT_LABEL_ALIGN_NONE,
+ UI_TEMPLATE_OP_PROPS_SHOW_EMPTY);
+
+ /* Hack: temporary hide.*/
+ for (int i = 0; i < ARRAY_SIZE(hide); i++) {
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, hide[i]);
+ if (prop) {
+ RNA_def_property_clear_flag(prop, PROP_HIDDEN);
+ }
+ }
UI_block_func_set(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL);
}
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 116cd700cc0..cb21659dbb8 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -720,7 +720,7 @@ static void file_ui_region_listener(
}
}
-static bool filepath_drop_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
+static bool filepath_drop_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
if (drag->type == WM_DRAG_PATH) {
SpaceFile *sfile = CTX_wm_space_file(C);
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 16658c0d8db..ad9af8cb948 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -86,7 +86,7 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d)
const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur);
int i;
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
GPU_line_width(1.0f);
@@ -103,7 +103,7 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d)
/* draw two black lines showing the standard reference levels */
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(shdr_pos, v2d->cur.xmin, env->midval + env->min);
immVertex2f(shdr_pos, v2d->cur.xmax, env->midval + env->min);
@@ -122,7 +122,7 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d)
/* for now, point color is fixed, and is white */
immUniformColor3f(1.0f, 1.0f, 1.0f);
- immBeginAtMost(GWN_PRIM_POINTS, env->totvert * 2);
+ immBeginAtMost(GPU_PRIM_POINTS, env->totvert * 2);
for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
/* only draw if visible
@@ -178,7 +178,7 @@ static void draw_fcurve_selected_keyframe_vertices(FCurve *fcu, View2D *v2d, boo
set_fcurve_vertex_color(fcu, sel);
- immBeginAtMost(GWN_PRIM_POINTS, fcu->totvert);
+ immBeginAtMost(GPU_PRIM_POINTS, fcu->totvert);
BezTriple *bezt = fcu->bezt;
for (int i = 0; i < fcu->totvert; i++, bezt++) {
@@ -230,7 +230,7 @@ static void draw_fcurve_selected_handle_vertices(FCurve *fcu, View2D *v2d, bool
immUniform4f("outlineColor", hcolor[0], hcolor[1], hcolor[2], 1.0f);
immUniformColor3fvAlpha(hcolor, 0.01f); /* almost invisible - only keep for smoothness */
- immBeginAtMost(GWN_PRIM_POINTS, fcu->totvert * 2);
+ immBeginAtMost(GPU_PRIM_POINTS, fcu->totvert * 2);
BezTriple *bezt = fcu->bezt;
BezTriple *prevbezt = NULL;
@@ -286,7 +286,7 @@ static void draw_fcurve_vertices(ARegion *ar, FCurve *fcu, bool do_handles, bool
* - draw handles before keyframes, so that keyframes will overlap handles (keyframes are more important for users)
*/
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
GPU_blend(true);
GPU_enable_program_point_size();
@@ -330,12 +330,12 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
{
int sel, b;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBeginAtMost(GWN_PRIM_LINES, 4 * 2 * fcu->totvert);
+ immBeginAtMost(GPU_PRIM_LINES, 4 * 2 * fcu->totvert);
/* slightly hacky, but we want to draw unselected points before selected ones
* so that selected points are clearly visible
@@ -422,12 +422,12 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
static void draw_fcurve_sample_control(float x, float y, float xscale, float yscale, float hsize, unsigned int pos)
{
/* adjust view transform before starting */
- gpuPushMatrix();
- gpuTranslate2f(x, y);
- gpuScale2f(1.0f / xscale * hsize, 1.0f / yscale * hsize);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(x, y);
+ GPU_matrix_scale_2f(1.0f / xscale * hsize, 1.0f / yscale * hsize);
/* draw X shape */
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, -0.7f, -0.7f);
immVertex2f(pos, +0.7f, +0.7f);
@@ -436,7 +436,7 @@ static void draw_fcurve_sample_control(float x, float y, float xscale, float ysc
immEnd();
/* restore view transform */
- gpuPopMatrix();
+ GPU_matrix_pop();
}
/* helper func - draw keyframe vertices only for an F-Curve */
@@ -459,7 +459,7 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) GPU_line_smooth(true);
GPU_blend(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor((fcu->flag & FCURVE_SELECTED) ? TH_TEXT_HI : TH_TEXT);
@@ -551,7 +551,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
n = (etime - stime) / samplefreq + 0.5f;
if (n > 0) {
- immBegin(GWN_PRIM_LINE_STRIP, (n + 1));
+ immBegin(GPU_PRIM_LINE_STRIP, (n + 1));
for (i = 0; i <= n; i++) {
float ctime = stime + i * samplefreq;
@@ -585,12 +585,12 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
}
/* apply unit mapping */
- gpuPushMatrix();
+ GPU_matrix_push();
unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
- gpuScale2f(1.0f, unit_scale);
- gpuTranslate2f(0.0f, offset);
+ GPU_matrix_scale_2f(1.0f, unit_scale);
+ GPU_matrix_translate_2f(0.0f, offset);
- immBegin(GWN_PRIM_LINE_STRIP, count);
+ immBegin(GPU_PRIM_LINE_STRIP, count);
/* extrapolate to left? - left-side of view comes before first keyframe? */
if (prevfpt->vec[0] > v2d->cur.xmin) {
@@ -645,7 +645,7 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
immEnd();
- gpuPopMatrix();
+ GPU_matrix_pop();
}
/* helper func - check if the F-Curve only contains easily drawable segments
@@ -679,15 +679,15 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
short mapping_flag = ANIM_get_normalization_flags(ac);
/* apply unit mapping */
- gpuPushMatrix();
+ GPU_matrix_push();
unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
- gpuScale2f(1.0f, unit_scale);
- gpuTranslate2f(0.0f, offset);
+ GPU_matrix_scale_2f(1.0f, unit_scale);
+ GPU_matrix_translate_2f(0.0f, offset);
/* For now, this assumes the worst case scenario, where all the keyframes have
* bezier interpolation, and are drawn at full res.
* This is tricky to optimize, but maybe can be improved at some point... */
- immBeginAtMost(GWN_PRIM_LINE_STRIP, (b * 32 + 3));
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, (b * 32 + 3));
/* extrapolate to left? */
if (prevbezt->vec[1][0] > v2d->cur.xmin) {
@@ -827,7 +827,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
immEnd();
- gpuPopMatrix();
+ GPU_matrix_pop();
}
/* Debugging -------------------------------- */
@@ -849,7 +849,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
//if ((driver->flag & DRIVER_FLAG_SHOWDEBUG) == 0)
// return;
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
@@ -874,7 +874,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
/* draw 1-1 line, stretching just past the screen limits
* NOTE: we need to scale the y-values to be valid for the units
*/
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
t = v2d->cur.xmin;
immVertex2f(shdr_pos, t, (t + offset) * unitfac);
@@ -900,7 +900,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
immUniform1f("dash_width", 10.0f);
immUniform1f("dash_factor", 0.5f);
- immBegin(GWN_PRIM_LINES, (y >= v2d->cur.ymin) ? 4 : 2);
+ immBegin(GPU_PRIM_LINES, (y >= v2d->cur.ymin) ? 4 : 2);
/* x-axis lookup */
co[0] = x;
@@ -926,7 +926,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
immUnbindProgram();
- /* GWN_PRIM_POINTS do not survive dashed line geometry shader... */
+ /* GPU_PRIM_POINTS do not survive dashed line geometry shader... */
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* x marks the spot .................................................... */
@@ -934,7 +934,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
immUniformColor3f(0.9f, 0.9f, 0.9f);
GPU_point_size(7.0);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex2f(shdr_pos, x, y);
immEnd();
@@ -942,7 +942,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
immUniformColor3f(0.9f, 0.0f, 0.0f);
GPU_point_size(3.0);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex2f(shdr_pos, x, y);
immEnd();
}
@@ -969,7 +969,7 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
}
GPU_blend(true);
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -1055,7 +1055,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
}
GPU_blend(true);
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -1136,9 +1136,9 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
/* apply unit-scaling to all values via OpenGL */
- gpuPushMatrix();
- gpuScale2f(1.0f, unit_scale);
- gpuTranslate2f(0.0f, offset);
+ GPU_matrix_push();
+ GPU_matrix_scale_2f(1.0f, unit_scale);
+ GPU_matrix_translate_2f(0.0f, offset);
/* set this once and for all - all handles and handle-verts should use the same thickness */
GPU_line_width(1.0);
@@ -1160,7 +1160,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
draw_fcurve_samples(sipo, ar, fcu);
}
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 699dc29ff47..fa57df0393a 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -279,7 +279,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
UI_view2d_grid_free(grid);
if (((sipo->flag & SIPO_NODRAWCURSOR) == 0) || (sipo->mode == SIPO_MODE_DRIVERS)) {
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -292,7 +292,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
GPU_blend(true);
GPU_line_width(2.0);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, v2d->cur.xmin, y);
immVertex2f(pos, v2d->cur.xmax, y);
immEnd();
@@ -310,7 +310,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
GPU_blend(true);
GPU_line_width(2.0);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, x, v2d->cur.ymin);
immVertex2f(pos, x, v2d->cur.ymax);
immEnd();
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 1d8c6721b64..afcae7a27ab 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -876,7 +876,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if (!compact) {
uiTemplateID(
layout, C, ptr, propname,
- ima ? NULL : "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ ima ? NULL : "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
}
if (ima) {
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 24b02106021..4cbe25462af 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -117,17 +117,17 @@ static void draw_render_info(const bContext *C,
int x, y;
UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
- gpuPushMatrix();
- gpuTranslate2f(x, y);
- gpuScale2f(zoomx, zoomy);
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(x, y);
+ GPU_matrix_scale_2f(zoomx, zoomy);
if (rd->mode & R_BORDER) {
/* TODO: round or floor instead of casting to int */
- gpuTranslate2f((int)(-rd->border.xmin * rd->xsch * rd->size * 0.01f),
+ GPU_matrix_translate_2f((int)(-rd->border.xmin * rd->xsch * rd->size * 0.01f),
(int)(-rd->border.ymin * rd->ysch * rd->size * 0.01f));
}
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_FACE_SELECT);
@@ -144,7 +144,7 @@ static void draw_render_info(const bContext *C,
MEM_freeN(tiles);
}
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
}
@@ -174,7 +174,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
GPU_blend(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* noisy, high contrast make impossible to read if lower alpha is used. */
@@ -330,7 +330,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
BLI_rcti_init(&color_rect, dx, dx + (1.5f * UI_UNIT_X), 0.15f * UI_UNIT_Y, 0.85f * UI_UNIT_Y);
/* BLF uses immediate mode too, so we must reset our vertex format */
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
if (channels == 4) {
@@ -367,7 +367,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
immUnbindProgram();
/* draw outline */
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3ub(128, 128, 128);
imm_draw_box_wire_2d(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
@@ -573,8 +573,8 @@ void draw_image_sample_line(SpaceImage *sima)
if (sima->sample_line_hist.flag & HISTO_FLAG_SAMPLELINE) {
Histogram *hist = &sima->sample_line_hist;
- Gwn_VertFormat *format = immVertexFormat();
- uint shdr_dashed_pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint shdr_dashed_pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -586,7 +586,7 @@ void draw_image_sample_line(SpaceImage *sima)
immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2);
immUniform1f("dash_width", 2.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2fv(shdr_dashed_pos, hist->co[0]);
immVertex2fv(shdr_dashed_pos, hist->co[1]);
immEnd();
@@ -779,7 +779,7 @@ void draw_image_cache(const bContext *C, ARegion *ar)
/* Draw current frame. */
x = (cfra - sfra) / (efra - sfra + 1) * ar->winx;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_CFRAME);
immRecti(pos, x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 29d63493a3c..be91f7abf99 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1410,7 +1410,7 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
return OPERATOR_RUNNING_MODAL;
}
-static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
+static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@@ -1429,7 +1429,7 @@ static void image_open_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
- uiDefAutoButsRNA(layout, &ptr, image_open_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
+ uiDefAutoButsRNA(layout, &ptr, image_open_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);
@@ -2124,7 +2124,7 @@ static void image_save_as_cancel(bContext *UNUSED(C), wmOperator *op)
image_save_as_free(op);
}
-static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@@ -2149,7 +2149,7 @@ static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
- uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
+ uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
/* multiview template */
if (is_multiview)
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 68b0f42768a..69bedf7c442 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -387,7 +387,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
}
/* dropboxes */
-static bool image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
if (drag->type == WM_DRAG_PATH)
if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */
@@ -581,25 +581,25 @@ static int image_context(const bContext *C, const char *member, bContextDataResu
return 0;
}
-static void IMAGE_WGT_gizmo2d(wmGizmoGroupType *wgt)
+static void IMAGE_GGT_gizmo2d(wmGizmoGroupType *gzgt)
{
- wgt->name = "UV Transform Gizmo";
- wgt->idname = "IMAGE_WGT_gizmo2d";
+ gzgt->name = "UV Transform Gizmo";
+ gzgt->idname = "IMAGE_GGT_gizmo2d";
- wgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT;
+ gzgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT;
- wgt->poll = ED_widgetgroup_gizmo2d_poll;
- wgt->setup = ED_widgetgroup_gizmo2d_setup;
- wgt->refresh = ED_widgetgroup_gizmo2d_refresh;
- wgt->draw_prepare = ED_widgetgroup_gizmo2d_draw_prepare;
+ gzgt->poll = ED_widgetgroup_gizmo2d_poll;
+ gzgt->setup = ED_widgetgroup_gizmo2d_setup;
+ gzgt->refresh = ED_widgetgroup_gizmo2d_refresh;
+ gzgt->draw_prepare = ED_widgetgroup_gizmo2d_draw_prepare;
}
static void image_widgets(void)
{
- wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure(
+ wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(
&(const struct wmGizmoMapType_Params){SPACE_IMAGE, RGN_TYPE_WINDOW});
- WM_gizmogrouptype_append_and_link(mmap_type, IMAGE_WGT_gizmo2d);
+ WM_gizmogrouptype_append_and_link(gzmap_type, IMAGE_GGT_gizmo2d);
}
/************************** main region ***************************/
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 3830e6d2792..fdf9d6df374 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -32,6 +32,7 @@
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_group_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
@@ -55,6 +56,7 @@
#include "BKE_particle.h"
#include "BKE_editmesh.h"
#include "BKE_object.h"
+#include "BKE_gpencil.h"
#include "ED_info.h"
#include "ED_armature.h"
@@ -72,6 +74,7 @@ typedef struct SceneStats {
int totobj, totobjsel;
int totlamp, totlampsel;
int tottri;
+ int totgplayer, totgpframe, totgpstroke, totgppoint;
char infostr[MAX_INFO_LEN];
} SceneStats;
@@ -85,6 +88,8 @@ typedef struct SceneStatsFmt {
char totobj[MAX_INFO_NUM_LEN], totobjsel[MAX_INFO_NUM_LEN];
char totlamp[MAX_INFO_NUM_LEN], totlampsel[MAX_INFO_NUM_LEN];
char tottri[MAX_INFO_NUM_LEN];
+ char totgplayer[MAX_INFO_NUM_LEN], totgpframe[MAX_INFO_NUM_LEN];
+ char totgpstroke[MAX_INFO_NUM_LEN], totgppoint[MAX_INFO_NUM_LEN];
} SceneStatsFmt;
static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
@@ -127,8 +132,8 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
{
int totv = 0, totf = 0, tottri = 0;
- if (ob->curve_cache && ob->curve_cache->disp.first)
- BKE_displist_count(&ob->curve_cache->disp, &totv, &totf, &tottri);
+ if (ob->runtime.curve_cache && ob->runtime.curve_cache->disp.first)
+ BKE_displist_count(&ob->runtime.curve_cache->disp, &totv, &totf, &tottri);
totv *= totob;
totf *= totob;
@@ -144,6 +149,20 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
}
break;
}
+ case OB_GPENCIL:
+ {
+ bGPdata *gpd = (bGPdata *)ob->data;
+ /* GPXX Review if we can move to other place when object change
+ * maybe to depsgraph evaluation
+ */
+ BKE_gpencil_stats_update(gpd);
+
+ stats->totgplayer = gpd->totlayer;
+ stats->totgpframe = gpd->totframe;
+ stats->totgpstroke = gpd->totstroke;
+ stats->totgppoint = gpd->totpoint;
+ break;
+ }
}
}
@@ -442,6 +461,11 @@ static void stats_string(ViewLayer *view_layer)
SCENE_STATS_FMT_INT(tottri);
+ SCENE_STATS_FMT_INT(totgplayer);
+ SCENE_STATS_FMT_INT(totgpframe);
+ SCENE_STATS_FMT_INT(totgpstroke);
+ SCENE_STATS_FMT_INT(totgppoint);
+
#undef SCENE_STATS_FMT_INT
@@ -501,6 +525,14 @@ static void stats_string(ViewLayer *view_layer)
ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Bones:%s/%s %s%s"),
stats_fmt.totbonesel, stats_fmt.totbone, memstr, gpumemstr);
}
+ else if ((ob) && (ob->type == OB_GPENCIL)) {
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs,
+ IFACE_("Layers:%s | Frames:%s | Strokes:%s | Points:%s"),
+ stats_fmt.totgplayer, stats_fmt.totgpframe, stats_fmt.totgpstroke, stats_fmt.totgppoint);
+
+ ofs += BLI_strncpy_rlen(s + ofs, memstr, MAX_INFO_LEN - ofs);
+ ofs += BLI_strncpy_rlen(s + ofs, gpumemstr, MAX_INFO_LEN - ofs);
+ }
else if (stats_is_object_dynamic_topology_sculpt(ob, object_mode)) {
ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%s | Tris:%s%s"), stats_fmt.totvert,
stats_fmt.tottri, gpumemstr);
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 5c1b23e140c..c94aaf6e861 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -85,8 +85,8 @@ static void console_draw_sel(const char *str, const int sel[2], const int xy[2],
GPU_blend(true);
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ubv(bg_sel);
@@ -191,8 +191,8 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
cdc->sel[1] = str_len - sel_orig[0];
if (bg) {
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3ubv(bg);
@@ -242,8 +242,8 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
else { /* simple, no wrap */
if (bg) {
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3ubv(bg);
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index 57464cbf092..40caf919848 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -145,6 +145,7 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p
case ANIMTYPE_DSLINESTYLE:
case ANIMTYPE_DSSPK:
case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_PALETTE:
{
/* for these channels, we only do AnimData */
if (ale->adt && adt_ptr) {
@@ -287,7 +288,7 @@ static void nla_panel_animdata(const bContext *C, Panel *pa)
row = uiLayoutRow(layout, true);
uiTemplateID(
row, (bContext *)C, &adt_ptr, "action",
- "ACTION_OT_new", NULL, "NLA_OT_action_unlink", UI_TEMPLATE_ID_FILTER_ALL);
+ "ACTION_OT_new", NULL, "NLA_OT_action_unlink", UI_TEMPLATE_ID_FILTER_ALL, false);
/* extrapolation */
row = uiLayoutRow(layout, true);
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index 3368ad4fe8d..51177a77f0d 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -182,6 +182,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
case ANIMTYPE_DSLINESTYLE:
case ANIMTYPE_DSSPK:
case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_PALETTE:
{
/* sanity checking... */
if (ale->adt) {
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 5b68c7b6bb7..7dd8c7f2eed 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -120,8 +120,8 @@ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, float y, floa
nla_action_get_color(adt, act, color);
color[3] *= 2.5f;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -142,13 +142,13 @@ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, float y, floa
if (key_len > 0) {
format = immVertexFormat();
- pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint size_id = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT);
- uint color_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
- uint outline_color_id = GWN_vertformat_attr_add(format, "outlineColor", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
GPU_enable_program_point_size();
- immBegin(GWN_PRIM_POINTS, key_len);
+ immBegin(GPU_PRIM_POINTS, key_len);
/* - disregard the selection status of keyframes so they draw a certain way
* - size is 6.0f which is smaller than the editable keyframes, so that there is a distinction
@@ -177,7 +177,7 @@ static void nla_actionclip_draw_markers(NlaStrip *strip, float yminc, float ymax
if (ELEM(NULL, act, act->markers.first))
return;
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (dashed) {
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -194,7 +194,7 @@ static void nla_actionclip_draw_markers(NlaStrip *strip, float yminc, float ymax
}
immUniformThemeColorShade(TH_STRIP_SELECT, shade);
- immBeginAtMost(GWN_PRIM_LINES, BLI_listbase_count(&act->markers) * 2);
+ immBeginAtMost(GPU_PRIM_LINES, BLI_listbase_count(&act->markers) * 2);
for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) {
if ((marker->frame > strip->actstart) && (marker->frame < strip->actend)) {
float frame = nlastrip_get_frame(strip, marker->frame, NLATIME_CONVERT_MAP);
@@ -318,7 +318,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uns
/* plot the curve (over the strip's main region) */
if (fcu) {
- immBegin(GWN_PRIM_LINE_STRIP, abs((int)(strip->end - strip->start) + 1));
+ immBegin(GPU_PRIM_LINE_STRIP, abs((int)(strip->end - strip->start) + 1));
/* sample at 1 frame intervals, and draw
* - min y-val is yminc, max is y-maxc, so clamp in those regions
@@ -335,7 +335,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uns
else {
/* use blend in/out values only if both aren't zero */
if ((IS_EQF(strip->blendin, 0.0f) && IS_EQF(strip->blendout, 0.0f)) == 0) {
- immBeginAtMost(GWN_PRIM_LINE_STRIP, 4);
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, 4);
/* start of strip - if no blendin, start straight at 1, otherwise from 0 to 1 over blendin frames */
if (IS_EQF(strip->blendin, 0.0f) == 0) {
@@ -366,7 +366,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uns
static uint nla_draw_use_dashed_outlines(float color[4], bool muted)
{
/* Note that we use dashed shader here, and make it draw solid lines if not muted... */
- uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
@@ -403,7 +403,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
/* get color of strip */
nla_strip_get_color_inside(adt, strip, color);
- shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* draw extrapolation info first (as backdrop)
@@ -456,7 +456,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
UI_draw_roundbox_shade_x(true, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1, color);
/* restore current vertex format & program (roundbox trashes it) */
- shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
}
else {
@@ -518,7 +518,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
/* only draw lines for whole-numbered repeats, starting from the first full-repeat
* up to the last full repeat (but not if it lies on the end of the strip)
*/
- immBeginAtMost(GWN_PRIM_LINES, 2 * floorf(strip->repeat));
+ immBeginAtMost(GPU_PRIM_LINES, 2 * floorf(strip->repeat));
for (int i = 1; i < strip->repeat; i++) {
float repeatPos = strip->start + (repeatLen * i);
@@ -534,7 +534,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
else if ((strip->type == NLASTRIP_TYPE_META) && (strip->strips.first != strip->strips.last)) {
const float y = (ymaxc - yminc) * 0.5f + yminc;
- immBeginAtMost(GWN_PRIM_LINES, 4 * BLI_listbase_count(&strip->strips)); /* up to 2 lines per strip */
+ immBeginAtMost(GPU_PRIM_LINES, 4 * BLI_listbase_count(&strip->strips)); /* up to 2 lines per strip */
/* only draw first-level of child-strips, but don't draw any lines on the endpoints */
for (NlaStrip *cs = strip->strips.first; cs; cs = cs->next) {
@@ -706,7 +706,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
{
AnimData *adt = ale->adt;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* just draw a semi-shaded rect spanning the width of the viewable area if there's data,
@@ -729,7 +729,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
/* white base-lines */
GPU_line_width(2.0f);
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.3f);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, v2d->cur.xmin, yminc + NLACHANNEL_SKIP);
immVertex2f(pos, v2d->cur.xmax, yminc + NLACHANNEL_SKIP);
immVertex2f(pos, v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP);
@@ -739,7 +739,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
/* black top-lines */
GPU_line_width(1.0f);
immUniformColor3f(0.0f, 0.0f, 0.0f);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, v2d->cur.xmin, yminc + NLACHANNEL_SKIP);
immVertex2f(pos, v2d->cur.xmax, yminc + NLACHANNEL_SKIP);
immVertex2f(pos, v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP);
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 97b112ebbd1..4dfbb92971b 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -744,7 +744,7 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA
PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
- uiTemplateID(layout, C, ptr, "image", "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "image", "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE);
uiItemR(layout, ptr, "interpolation", 0, "", ICON_NONE);
uiItemR(layout, ptr, "projection", 0, "", ICON_NONE);
@@ -775,7 +775,7 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin
uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
uiTemplateID(
layout, C, ptr, "image",
- "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr, false);
@@ -793,7 +793,7 @@ static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, P
uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
uiTemplateID(
layout, C, ptr, "image",
- "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
if (!ima)
return;
@@ -1025,6 +1025,11 @@ static void node_shader_buts_hair(uiLayout *layout, bContext *UNUSED(C), Pointer
uiItemR(layout, ptr, "component", 0, "", ICON_NONE);
}
+static void node_shader_buts_principled_hair(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "parametrization", 0, "", ICON_NONE);
+}
+
static void node_shader_buts_ies(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *row;
@@ -1207,6 +1212,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_BSDF_HAIR:
ntype->draw_buttons = node_shader_buts_hair;
break;
+ case SH_NODE_BSDF_HAIR_PRINCIPLED:
+ ntype->draw_buttons = node_shader_buts_principled_hair;
+ break;
case SH_NODE_SCRIPT:
ntype->draw_buttons = node_shader_buts_script;
ntype->draw_buttons_ex = node_shader_buts_script_ex;
@@ -1266,7 +1274,7 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *
uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
uiTemplateID(
layout, C, ptr, "image",
- "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
if (!node->id) return;
imaptr = RNA_pointer_get(ptr, "image");
@@ -1296,7 +1304,7 @@ static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, Pointer
const char *layer_name;
char scene_name[MAX_ID_NAME - 2];
- uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
if (!node->id) return;
@@ -1410,7 +1418,7 @@ static void node_composit_buts_defocus(uiLayout *layout, bContext *C, PointerRNA
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "use_preview", 0, NULL, ICON_NONE);
- uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "use_zbuffer", 0, NULL, ICON_NONE);
@@ -1977,7 +1985,7 @@ static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), Pointe
static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
}
static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -1985,7 +1993,7 @@ static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, Point
bNode *node = ptr->data;
PointerRNA clipptr;
- uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
if (!node->id)
return;
@@ -1999,7 +2007,7 @@ static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, Pointe
{
bNode *node = ptr->data;
- uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
if (!node->id)
return;
@@ -2023,7 +2031,7 @@ static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, Po
{
bNode *node = ptr->data;
- uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
if (!node->id)
return;
@@ -2184,14 +2192,14 @@ static void node_composit_backdrop_viewer(SpaceNode *snode, ImBuf *backdrop, bNo
const float cy = y + snode->zoom * backdropHeight * node->custom4;
const float cross_size = 12 * U.pixelsize;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3f(1.0f, 1.0f, 1.0f);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, cx - cross_size, cy - cross_size);
immVertex2f(pos, cx + cross_size, cy + cross_size);
immVertex2f(pos, cx + cross_size, cy - cross_size);
@@ -2229,14 +2237,14 @@ static void node_composit_backdrop_boxmask(SpaceNode *snode, ImBuf *backdrop, bN
y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3f(1.0f, 1.0f, 1.0f);
- immBegin(GWN_PRIM_LINE_LOOP, 4);
+ immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex2f(pos, x1, y1);
immVertex2f(pos, x2, y2);
immVertex2f(pos, x3, y3);
@@ -2273,14 +2281,14 @@ static void node_composit_backdrop_ellipsemask(SpaceNode *snode, ImBuf *backdrop
y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3f(1.0f, 1.0f, 1.0f);
- immBegin(GWN_PRIM_LINE_LOOP, 4);
+ immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex2f(pos, x1, y1);
immVertex2f(pos, x2, y2);
immVertex2f(pos, x3, y3);
@@ -2331,7 +2339,7 @@ static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *p
{
bNode *node = ptr->data;
- uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
uiItemR(layout, ptr, "use_antialiasing", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_feather", 0, NULL, ICON_NONE);
@@ -2353,7 +2361,7 @@ static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, Point
{
bNode *node = ptr->data;
- uiTemplateID(layout, C, ptr, "clip", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "clip", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
if (node->id) {
MovieClip *clip = (MovieClip *) node->id;
@@ -2389,7 +2397,7 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN
{
bNode *node = ptr->data;
- uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
if (node->id) {
MovieClip *clip = (MovieClip *) node->id;
@@ -2429,7 +2437,7 @@ static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, P
bNode *node = ptr->data;
NodePlaneTrackDeformData *data = node->storage;
- uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
if (node->id) {
MovieClip *clip = (MovieClip *) node->id;
@@ -2473,6 +2481,25 @@ static void node_composit_buts_sunbeams(uiLayout *layout, bContext *UNUSED(C), P
uiItemR(layout, ptr, "ray_length", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
}
+static void node_composit_buts_cryptomatte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *col = uiLayoutColumn(layout, true);
+
+ uiItemL(col, IFACE_("Matte Objects:"), ICON_NONE);
+
+ uiLayout *row = uiLayoutRow(col, true);
+ uiTemplateCryptoPicker(row, ptr, "add");
+ uiTemplateCryptoPicker(row, ptr, "remove");
+
+ uiItemR(col, ptr, "matte_id", 0, "", ICON_NONE);
+}
+
+static void node_composit_buts_cryptomatte_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *UNUSED(ptr))
+{
+ uiItemO(layout, IFACE_("Add Crypto Layer"), ICON_ZOOMIN, "NODE_OT_cryptomatte_layer_add");
+ uiItemO(layout, IFACE_("Remove Crypto Layer"), ICON_ZOOMOUT, "NODE_OT_cryptomatte_layer_remove");
+}
+
static void node_composit_buts_brightcontrast(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "use_premultiply", 0, NULL, ICON_NONE);
@@ -2705,6 +2732,10 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_SUNBEAMS:
ntype->draw_buttons = node_composit_buts_sunbeams;
break;
+ case CMP_NODE_CRYPTOMATTE:
+ ntype->draw_buttons = node_composit_buts_cryptomatte;
+ ntype->draw_buttons_ex = node_composit_buts_cryptomatte_ex;
+ break;
case CMP_NODE_BRIGHTCONTRAST:
ntype->draw_buttons = node_composit_buts_brightcontrast;
}
@@ -2807,7 +2838,7 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- uiTemplateID(layout, C, ptr, "image", "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
+ uiTemplateID(layout, C, ptr, "image", "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
}
static void node_texture_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -3193,8 +3224,8 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
if (ibuf) {
float x, y;
- gpuPushProjectionMatrix();
- gpuPushMatrix();
+ GPU_matrix_push_projection();
+ GPU_matrix_push();
/* somehow the offset has to be calculated inverse */
wmOrtho2_region_pixelspace(ar);
@@ -3267,7 +3298,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
y + snode->zoom * viewer_border->ymin * ibuf->y,
y + snode->zoom * viewer_border->ymax * ibuf->y);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_ACTIVE);
@@ -3277,8 +3308,8 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
}
}
- gpuPopProjectionMatrix();
- gpuPopMatrix();
+ GPU_matrix_pop_projection();
+ GPU_matrix_pop();
}
BKE_image_release_ibuf(ima, ibuf, lock);
@@ -3322,7 +3353,16 @@ static bool node_link_bezier_handles(View2D *v2d, SpaceNode *snode, bNodeLink *l
}
/* may be called outside of drawing (so pass spacetype) */
- dist = UI_GetThemeValueType(TH_NODE_CURVING, SPACE_NODE) * 0.10f * fabsf(vec[0][0] - vec[3][0]);
+ int curving = UI_GetThemeValueType(TH_NODE_CURVING, SPACE_NODE);
+
+ if (curving == 0) {
+ /* Straight line: align all points. */
+ mid_v2_v2v2(vec[1], vec[0], vec[3]);
+ mid_v2_v2v2(vec[2], vec[1], vec[3]);
+ return 1;
+ }
+
+ dist = curving * 0.10f * fabsf(vec[0][0] - vec[3][0]);
deltax = vec[3][0] - vec[0][0];
deltay = vec[3][1] - vec[0][1];
/* check direction later, for top sockets */
@@ -3391,51 +3431,51 @@ bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, flo
static float arrow_verts[3][2] = {{-1.0f, 1.0f}, {0.0f, 0.0f}, {-1.0f, -1.0f}};
static float arrow_expand_axis[3][2] = {{0.7071f, 0.7071f}, {M_SQRT2, 0.0f}, {0.7071f, -0.7071f}};
-struct {
- Gwn_Batch *batch; /* for batching line together */
- Gwn_Batch *batch_single; /* for single line */
- Gwn_VertBuf *inst_vbo;
+static struct {
+ GPUBatch *batch; /* for batching line together */
+ GPUBatch *batch_single; /* for single line */
+ GPUVertBuf *inst_vbo;
unsigned int p0_id, p1_id, p2_id, p3_id;
unsigned int colid_id;
- Gwn_VertBufRaw p0_step, p1_step, p2_step, p3_step;
- Gwn_VertBufRaw colid_step;
+ GPUVertBufRaw p0_step, p1_step, p2_step, p3_step;
+ GPUVertBufRaw colid_step;
unsigned int count;
bool enabled;
} g_batch_link = {0};
static void nodelink_batch_reset(void)
{
- GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p0_id, &g_batch_link.p0_step);
- GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p1_id, &g_batch_link.p1_step);
- GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p2_id, &g_batch_link.p2_step);
- GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p3_id, &g_batch_link.p3_step);
- GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.colid_id, &g_batch_link.colid_step);
+ GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p0_id, &g_batch_link.p0_step);
+ GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p1_id, &g_batch_link.p1_step);
+ GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p2_id, &g_batch_link.p2_step);
+ GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p3_id, &g_batch_link.p3_step);
+ GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.colid_id, &g_batch_link.colid_step);
g_batch_link.count = 0;
}
static void set_nodelink_vertex(
- Gwn_VertBuf *vbo,
+ GPUVertBuf *vbo,
unsigned int uv_id, unsigned int pos_id, unsigned int exp_id, unsigned int v,
const unsigned char uv[2], const float pos[2], const float exp[2])
{
- GWN_vertbuf_attr_set(vbo, uv_id, v, uv);
- GWN_vertbuf_attr_set(vbo, pos_id, v, pos);
- GWN_vertbuf_attr_set(vbo, exp_id, v, exp);
+ GPU_vertbuf_attr_set(vbo, uv_id, v, uv);
+ GPU_vertbuf_attr_set(vbo, pos_id, v, pos);
+ GPU_vertbuf_attr_set(vbo, exp_id, v, exp);
}
static void nodelink_batch_init(void)
{
- Gwn_VertFormat format = {0};
- uint uv_id = GWN_vertformat_attr_add(&format, "uv", GWN_COMP_U8, 2, GWN_FETCH_INT_TO_FLOAT_UNIT);
- uint pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint expand_id = GWN_vertformat_attr_add(&format, "expand", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format_ex(&format, GWN_USAGE_STATIC);
+ GPUVertFormat format = {0};
+ uint uv_id = GPU_vertformat_attr_add(&format, "uv", GPU_COMP_U8, 2, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint expand_id = GPU_vertformat_attr_add(&format, "expand", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC);
int vcount = LINK_RESOL * 2; /* curve */
vcount += 2; /* restart strip */
vcount += 3 * 2; /* arrow */
vcount *= 2; /* shadow */
vcount += 2; /* restart strip */
- GWN_vertbuf_data_alloc(vbo, vcount);
+ GPU_vertbuf_data_alloc(vbo, vcount);
int v = 0;
for (int k = 0; k < 2; ++k) {
@@ -3479,23 +3519,23 @@ static void nodelink_batch_init(void)
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
}
- g_batch_link.batch = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ g_batch_link.batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
gpu_batch_presets_register(g_batch_link.batch);
- g_batch_link.batch_single = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, 0);
+ g_batch_link.batch_single = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, 0);
gpu_batch_presets_register(g_batch_link.batch_single);
/* Instances data */
- Gwn_VertFormat format_inst = {0};
- g_batch_link.p0_id = GWN_vertformat_attr_add(&format_inst, "P0", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- g_batch_link.p1_id = GWN_vertformat_attr_add(&format_inst, "P1", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- g_batch_link.p2_id = GWN_vertformat_attr_add(&format_inst, "P2", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- g_batch_link.p3_id = GWN_vertformat_attr_add(&format_inst, "P3", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- g_batch_link.colid_id = GWN_vertformat_attr_add(&format_inst, "colid_doarrow", GWN_COMP_U8, 4, GWN_FETCH_INT);
- g_batch_link.inst_vbo = GWN_vertbuf_create_with_format_ex(&format_inst, GWN_USAGE_STREAM);
- GWN_vertbuf_data_alloc(g_batch_link.inst_vbo, NODELINK_GROUP_SIZE); /* Alloc max count but only draw the range we need. */
+ GPUVertFormat format_inst = {0};
+ g_batch_link.p0_id = GPU_vertformat_attr_add(&format_inst, "P0", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ g_batch_link.p1_id = GPU_vertformat_attr_add(&format_inst, "P1", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ g_batch_link.p2_id = GPU_vertformat_attr_add(&format_inst, "P2", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ g_batch_link.p3_id = GPU_vertformat_attr_add(&format_inst, "P3", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ g_batch_link.colid_id = GPU_vertformat_attr_add(&format_inst, "colid_doarrow", GPU_COMP_U8, 4, GPU_FETCH_INT);
+ g_batch_link.inst_vbo = GPU_vertbuf_create_with_format_ex(&format_inst, GPU_USAGE_STREAM);
+ GPU_vertbuf_data_alloc(g_batch_link.inst_vbo, NODELINK_GROUP_SIZE); /* Alloc max count but only draw the range we need. */
- GWN_batch_instbuf_set(g_batch_link.batch, g_batch_link.inst_vbo, true);
+ GPU_batch_instbuf_set(g_batch_link.batch, g_batch_link.inst_vbo, true);
nodelink_batch_reset();
}
@@ -3526,14 +3566,14 @@ static void nodelink_batch_draw(SpaceNode *snode)
UI_GetThemeColor4fv(TH_EDGE_SELECT, colors[nodelink_get_color_id(TH_EDGE_SELECT)]);
UI_GetThemeColor4fv(TH_REDALERT, colors[nodelink_get_color_id(TH_REDALERT)]);
- GWN_vertbuf_vertex_count_set(g_batch_link.inst_vbo, g_batch_link.count);
- GWN_vertbuf_use(g_batch_link.inst_vbo); /* force update. */
+ GPU_vertbuf_vertex_count_set(g_batch_link.inst_vbo, g_batch_link.count);
+ GPU_vertbuf_use(g_batch_link.inst_vbo); /* force update. */
- GWN_batch_program_set_builtin(g_batch_link.batch, GPU_SHADER_2D_NODELINK_INST);
- GWN_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, (float *)colors);
- GWN_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->aspect * LINK_WIDTH);
- GWN_batch_uniform_1f(g_batch_link.batch, "arrowSize", ARROW_SIZE);
- GWN_batch_draw(g_batch_link.batch);
+ GPU_batch_program_set_builtin(g_batch_link.batch, GPU_SHADER_2D_NODELINK_INST);
+ GPU_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, (float *)colors);
+ GPU_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->aspect * LINK_WIDTH);
+ GPU_batch_uniform_1f(g_batch_link.batch, "arrowSize", ARROW_SIZE);
+ GPU_batch_draw(g_batch_link.batch);
nodelink_batch_reset();
@@ -3562,11 +3602,11 @@ static void nodelink_batch_add_link(
BLI_assert(ELEM(th_col3, TH_WIRE, -1));
g_batch_link.count++;
- copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p0_step), p0);
- copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p1_step), p1);
- copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p2_step), p2);
- copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p3_step), p3);
- char *colid = GWN_vertbuf_raw_step(&g_batch_link.colid_step);
+ copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p0_step), p0);
+ copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p1_step), p1);
+ copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p2_step), p2);
+ copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p3_step), p3);
+ char *colid = GPU_vertbuf_raw_step(&g_batch_link.colid_step);
colid[0] = nodelink_get_color_id(th_col1);
colid[1] = nodelink_get_color_id(th_col2);
colid[2] = nodelink_get_color_id(th_col3);
@@ -3604,14 +3644,14 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
UI_GetThemeColor4fv(th_col1, colors[1]);
UI_GetThemeColor4fv(th_col2, colors[2]);
- Gwn_Batch *batch = g_batch_link.batch_single;
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK);
- GWN_batch_uniform_2fv_array(batch, "bezierPts", 4, (float *)vec);
- GWN_batch_uniform_4fv_array(batch, "colors", 3, (float *)colors);
- GWN_batch_uniform_1f(batch, "expandSize", snode->aspect * LINK_WIDTH);
- GWN_batch_uniform_1f(batch, "arrowSize", ARROW_SIZE);
- GWN_batch_uniform_1i(batch, "doArrow", drawarrow);
- GWN_batch_draw(batch);
+ GPUBatch *batch = g_batch_link.batch_single;
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK);
+ GPU_batch_uniform_2fv_array(batch, "bezierPts", 4, (float *)vec);
+ GPU_batch_uniform_4fv_array(batch, "colors", 3, (float *)colors);
+ GPU_batch_uniform_1f(batch, "expandSize", snode->aspect * LINK_WIDTH);
+ GPU_batch_uniform_1f(batch, "arrowSize", ARROW_SIZE);
+ GPU_batch_uniform_1i(batch, "doArrow", drawarrow);
+ GPU_batch_draw(batch);
}
}
}
@@ -3660,7 +3700,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder border, unsigned pos)
{
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
if (border & (NODE_LEFT | NODE_RIGHT)) {
immVertex2f(pos, cent[0], v2d->cur.ymin);
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index c632b354440..bba46771674 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -648,8 +648,8 @@ static void node_draw_preview_background(float tile, rctf *rect)
{
float x, y;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -721,7 +721,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
GPU_blend(false);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShadeAlpha(TH_BACK, -15, +100);
imm_draw_box_wire_2d(pos, draw_rect.xmin, draw_rect.ymin, draw_rect.xmax, draw_rect.ymax);
@@ -771,9 +771,9 @@ void node_draw_sockets(View2D *v2d, const bContext *C, bNodeTree *ntree, bNode *
float scale;
UI_view2d_scale_get(v2d, &scale, NULL);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
GPU_blend(true);
GPU_enable_program_point_size();
@@ -788,7 +788,7 @@ void node_draw_sockets(View2D *v2d, const bContext *C, bNodeTree *ntree, bNode *
immUniform1f("outlineWidth", 1.0f);
immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 0.6f);
- immBeginAtMost(GWN_PRIM_POINTS, total_input_len + total_output_len);
+ immBeginAtMost(GPU_PRIM_POINTS, total_input_len + total_output_len);
}
/* socket inputs */
@@ -832,7 +832,7 @@ void node_draw_sockets(View2D *v2d, const bContext *C, bNodeTree *ntree, bNode *
immUniform4f("outlineColor", c[0], c[1], c[2], 1.0f);
immUniform1f("outlineWidth", 1.5f);
- immBegin(GWN_PRIM_POINTS, selected_input_len + selected_output_len);
+ immBegin(GPU_PRIM_POINTS, selected_input_len + selected_output_len);
if (selected_input_len) {
/* socket inputs */
@@ -951,18 +951,18 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* open/close entirely? */
{
uiBut *but;
- int but_size = UI_UNIT_X * 0.6f;
+ int but_size = UI_UNIT_X * 1.2f;
/* XXX button uses a custom triangle draw below, so make it invisible without icon */
UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "",
- rct->xmin + 0.5f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2,
+ rct->xmin + 0.6f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.2f - but_size / 2,
but_size, but_size, NULL, 0, 0, 0, 0, "");
UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
UI_block_emboss_set(node->block, UI_EMBOSS);
UI_GetThemeColor4fv(TH_TEXT, color);
/* custom draw function for this button */
- UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v', color);
+ UI_draw_icon_tri(rct->xmin + 0.6f * U.widget_unit, rct->ymax - NODE_DY / 2.2f, 'v', color);
}
nodeLabel(ntree, node, showname, sizeof(showname));
@@ -1071,7 +1071,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
/* open entirely icon */
{
uiBut *but;
- int but_size = UI_UNIT_X * 0.6f;
+ int but_size = UI_UNIT_X * 1.2f;
/* XXX button uses a custom triangle draw below, so make it invisible without icon */
UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "",
@@ -1102,13 +1102,13 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
}
/* scale widget thing */
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShade(color_id, -10);
dx = 10.0f;
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
@@ -1119,7 +1119,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
immUniformThemeColorShade(color_id, 30);
dx -= snode->aspect;
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
@@ -1405,17 +1405,17 @@ void drawnodespace(const bContext *C, ARegion *ar)
{
float original_proj[4][4];
- gpuGetProjectionMatrix(original_proj);
+ GPU_matrix_projection_get(original_proj);
- gpuPushMatrix();
- gpuLoadIdentity();
+ GPU_matrix_push();
+ GPU_matrix_identity_set();
wmOrtho2_pixelspace(ar->winx, ar->winy);
WM_gizmomap_draw(ar->gizmo_map, C, WM_GIZMOMAP_DRAWSTEP_2D);
- gpuPopMatrix();
- gpuLoadProjectionMatrix(original_proj);
+ GPU_matrix_pop();
+ GPU_matrix_projection_set(original_proj);
}
draw_nodetree(C, ar, ntree, path->parent_key);
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 1a6710035c2..edab76cd7e1 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -2548,3 +2548,93 @@ void NODE_OT_clear_viewer_border(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+/* ****************** Cryptomatte Add Socket ******************* */
+
+static int node_cryptomatte_add_socket_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ PointerRNA ptr = CTX_data_pointer_get(C, "node");
+ bNodeTree *ntree = NULL;
+ bNode *node = NULL;
+
+ if (ptr.data) {
+ node = ptr.data;
+ ntree = ptr.id.data;
+ }
+ else if (snode && snode->edittree) {
+ ntree = snode->edittree;
+ node = nodeGetActive(snode->edittree);
+ }
+
+ if (!node || node->type != CMP_NODE_CRYPTOMATTE) {
+ return OPERATOR_CANCELLED;
+ }
+
+ ntreeCompositCryptomatteAddSocket(ntree, node);
+
+ snode_notify(C, snode);
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_cryptomatte_layer_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Cryptomatte Socket";
+ ot->description = "Add a new input layer to a Cryptomatte node";
+ ot->idname = "NODE_OT_cryptomatte_layer_add";
+
+ /* callbacks */
+ ot->exec = node_cryptomatte_add_socket_exec;
+ ot->poll = composite_node_editable;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ****************** Cryptomatte Remove Socket ******************* */
+
+static int node_cryptomatte_remove_socket_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ PointerRNA ptr = CTX_data_pointer_get(C, "node");
+ bNodeTree *ntree = NULL;
+ bNode *node = NULL;
+
+ if (ptr.data) {
+ node = ptr.data;
+ ntree = ptr.id.data;
+ }
+ else if (snode && snode->edittree) {
+ ntree = snode->edittree;
+ node = nodeGetActive(snode->edittree);
+ }
+
+ if (!node || node->type != CMP_NODE_CRYPTOMATTE) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!ntreeCompositCryptomatteRemoveSocket(ntree, node)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ snode_notify(C, snode);
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_cryptomatte_layer_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Cryptomatte Socket";
+ ot->description = "Remove layer from a Crytpomatte node";
+ ot->idname = "NODE_OT_cryptomatte_layer_remove";
+
+ /* callbacks */
+ ot->exec = node_cryptomatte_remove_socket_exec;
+ ot->poll = composite_node_editable;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/space_node/node_gizmo.c b/source/blender/editors/space_node/node_gizmo.c
index 37ea53aa710..b265d95c06a 100644
--- a/source/blender/editors/space_node/node_gizmo.c
+++ b/source/blender/editors/space_node/node_gizmo.c
@@ -83,12 +83,12 @@ static void node_gizmo_calc_matrix_space_with_image_dims(
* \{ */
static void gizmo_node_backdrop_prop_matrix_get(
- const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop,
+ const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
void *value_p)
{
float (*matrix)[4] = value_p;
- BLI_assert(mpr_prop->type->array_length == 16);
- const SpaceNode *snode = mpr_prop->custom_func.user_data;
+ BLI_assert(gz_prop->type->array_length == 16);
+ const SpaceNode *snode = gz_prop->custom_func.user_data;
matrix[0][0] = snode->zoom;
matrix[1][1] = snode->zoom;
matrix[3][0] = snode->xof;
@@ -96,19 +96,19 @@ static void gizmo_node_backdrop_prop_matrix_get(
}
static void gizmo_node_backdrop_prop_matrix_set(
- const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop,
+ const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
const void *value_p)
{
const float (*matrix)[4] = value_p;
- BLI_assert(mpr_prop->type->array_length == 16);
- SpaceNode *snode = mpr_prop->custom_func.user_data;
+ BLI_assert(gz_prop->type->array_length == 16);
+ SpaceNode *snode = gz_prop->custom_func.user_data;
snode->zoom = matrix[0][0];
snode->zoom = matrix[1][1];
snode->xof = matrix[3][0];
snode->yof = matrix[3][1];
}
-static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -127,22 +127,22 @@ static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmGizmoGroupType
return false;
}
-static void WIDGETGROUP_node_transform_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_node_transform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
- wwrapper->gizmo = WM_gizmo_new("GIZMO_WT_cage_2d", mgroup, NULL);
+ wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
RNA_enum_set(wwrapper->gizmo->ptr, "transform",
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM);
- mgroup->customdata = wwrapper;
+ gzgroup->customdata = wwrapper;
}
-static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
Main *bmain = CTX_data_main(C);
- wmGizmo *cage = ((wmGizmoWrapper *)mgroup->customdata)->gizmo;
+ wmGizmo *cage = ((wmGizmoWrapper *)gzgroup->customdata)->gizmo;
const ARegion *ar = CTX_wm_region(C);
/* center is always at the origin */
const float origin[3] = {ar->winx / 2, ar->winy / 2};
@@ -186,16 +186,16 @@ static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmGizmoGroup *
BKE_image_release_ibuf(ima, ibuf, lock);
}
-void NODE_WGT_backdrop_transform(wmGizmoGroupType *wgt)
+void NODE_GGT_backdrop_transform(wmGizmoGroupType *gzgt)
{
- wgt->name = "Backdrop Transform Widget";
- wgt->idname = "NODE_WGT_backdrop_transform";
+ gzgt->name = "Backdrop Transform Widget";
+ gzgt->idname = "NODE_GGT_backdrop_transform";
- wgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT;
+ gzgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT;
- wgt->poll = WIDGETGROUP_node_transform_poll;
- wgt->setup = WIDGETGROUP_node_transform_setup;
- wgt->refresh = WIDGETGROUP_node_transform_refresh;
+ gzgt->poll = WIDGETGROUP_node_transform_poll;
+ gzgt->setup = WIDGETGROUP_node_transform_setup;
+ gzgt->refresh = WIDGETGROUP_node_transform_refresh;
}
/** \} */
@@ -258,14 +258,14 @@ static void two_xy_from_rect(NodeTwoXYs *nxy, const rctf *rect, const float dims
/* scale callbacks */
static void gizmo_node_crop_prop_matrix_get(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
void *value_p)
{
float (*matrix)[4] = value_p;
- BLI_assert(mpr_prop->type->array_length == 16);
- struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata;
+ BLI_assert(gz_prop->type->array_length == 16);
+ struct NodeCropWidgetGroup *crop_group = gz->parent_gzgroup->customdata;
const float *dims = crop_group->state.dims;
- const bNode *node = mpr_prop->custom_func.user_data;
+ const bNode *node = gz_prop->custom_func.user_data;
const NodeTwoXYs *nxy = node->storage;
bool is_relative = (bool)node->custom2;
rctf rct;
@@ -277,14 +277,14 @@ static void gizmo_node_crop_prop_matrix_get(
}
static void gizmo_node_crop_prop_matrix_set(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
const void *value_p)
{
const float (*matrix)[4] = value_p;
- BLI_assert(mpr_prop->type->array_length == 16);
- struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata;
+ BLI_assert(gz_prop->type->array_length == 16);
+ struct NodeCropWidgetGroup *crop_group = gz->parent_gzgroup->customdata;
const float *dims = crop_group->state.dims;
- bNode *node = mpr_prop->custom_func.user_data;
+ bNode *node = gz_prop->custom_func.user_data;
NodeTwoXYs *nxy = node->storage;
bool is_relative = (bool)node->custom2;
rctf rct;
@@ -296,7 +296,7 @@ static void gizmo_node_crop_prop_matrix_set(
gizmo_node_crop_update(crop_group);
}
-static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -318,33 +318,33 @@ static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmGizmoGroupType *UNUS
return false;
}
-static void WIDGETGROUP_node_crop_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_node_crop_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
struct NodeCropWidgetGroup *crop_group = MEM_mallocN(sizeof(struct NodeCropWidgetGroup), __func__);
- crop_group->border = WM_gizmo_new("GIZMO_WT_cage_2d", mgroup, NULL);
+ crop_group->border = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
RNA_enum_set(crop_group->border->ptr, "transform",
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
- mgroup->customdata = crop_group;
+ gzgroup->customdata = crop_group;
}
-static void WIDGETGROUP_node_crop_draw_prepare(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_node_crop_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
ARegion *ar = CTX_wm_region(C);
- wmGizmo *mpr = mgroup->gizmos.first;
+ wmGizmo *gz = gzgroup->gizmos.first;
SpaceNode *snode = CTX_wm_space_node(C);
- node_gizmo_calc_matrix_space(snode, ar, mpr->matrix_space);
+ node_gizmo_calc_matrix_space(snode, ar, gz->matrix_space);
}
-static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
Main *bmain = CTX_data_main(C);
- struct NodeCropWidgetGroup *crop_group = mgroup->customdata;
- wmGizmo *mpr = crop_group->border;
+ struct NodeCropWidgetGroup *crop_group = gzgroup->customdata;
+ wmGizmo *gz = crop_group->border;
void *lock;
Image *ima = BKE_image_verify_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
@@ -354,8 +354,8 @@ static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *mgrou
crop_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f;
crop_group->state.dims[1] = (ibuf->y > 0) ? ibuf->y : 64.0f;
- RNA_float_set_array(mpr->ptr, "dimensions", crop_group->state.dims);
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false);
+ RNA_float_set_array(gz->ptr, "dimensions", crop_group->state.dims);
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node = nodeGetActive(snode->edittree);
@@ -365,7 +365,7 @@ static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *mgrou
crop_group->update_data.prop = RNA_struct_find_property(&crop_group->update_data.ptr, "relative");
WM_gizmo_target_property_def_func(
- mpr, "matrix",
+ gz, "matrix",
&(const struct wmGizmoPropertyFnParams) {
.value_get_fn = gizmo_node_crop_prop_matrix_get,
.value_set_fn = gizmo_node_crop_prop_matrix_set,
@@ -374,23 +374,23 @@ static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *mgrou
});
}
else {
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
}
BKE_image_release_ibuf(ima, ibuf, lock);
}
-void NODE_WGT_backdrop_crop(wmGizmoGroupType *wgt)
+void NODE_GGT_backdrop_crop(wmGizmoGroupType *gzgt)
{
- wgt->name = "Backdrop Crop Widget";
- wgt->idname = "NODE_WGT_backdrop_crop";
+ gzgt->name = "Backdrop Crop Widget";
+ gzgt->idname = "NODE_GGT_backdrop_crop";
- wgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT;
+ gzgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT;
- wgt->poll = WIDGETGROUP_node_crop_poll;
- wgt->setup = WIDGETGROUP_node_crop_setup;
- wgt->draw_prepare = WIDGETGROUP_node_crop_draw_prepare;
- wgt->refresh = WIDGETGROUP_node_crop_refresh;
+ gzgt->poll = WIDGETGROUP_node_crop_poll;
+ gzgt->setup = WIDGETGROUP_node_crop_setup;
+ gzgt->draw_prepare = WIDGETGROUP_node_crop_draw_prepare;
+ gzgt->refresh = WIDGETGROUP_node_crop_refresh;
}
/** \} */
@@ -408,7 +408,7 @@ struct NodeSunBeamsWidgetGroup {
} state;
};
-static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -427,36 +427,36 @@ static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmGizmoGroupType *UNU
return false;
}
-static void WIDGETGROUP_node_sbeam_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_node_sbeam_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
struct NodeSunBeamsWidgetGroup *sbeam_group = MEM_mallocN(sizeof(struct NodeSunBeamsWidgetGroup), __func__);
- sbeam_group->gizmo = WM_gizmo_new("GIZMO_WT_grab_3d", mgroup, NULL);
- wmGizmo *mpr = sbeam_group->gizmo;
+ sbeam_group->gizmo = WM_gizmo_new("GIZMO_GT_grab_3d", gzgroup, NULL);
+ wmGizmo *gz = sbeam_group->gizmo;
- RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_CROSS_2D);
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_CROSS_2D);
- mpr->scale_basis = 0.05f;
+ gz->scale_basis = 0.05f;
- mgroup->customdata = sbeam_group;
+ gzgroup->customdata = sbeam_group;
}
-static void WIDGETGROUP_node_sbeam_draw_prepare(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_node_sbeam_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct NodeSunBeamsWidgetGroup *sbeam_group = mgroup->customdata;
+ struct NodeSunBeamsWidgetGroup *sbeam_group = gzgroup->customdata;
ARegion *ar = CTX_wm_region(C);
- wmGizmo *mpr = mgroup->gizmos.first;
+ wmGizmo *gz = gzgroup->gizmos.first;
SpaceNode *snode = CTX_wm_space_node(C);
- node_gizmo_calc_matrix_space_with_image_dims(snode, ar, sbeam_group->state.dims, mpr->matrix_space);
+ node_gizmo_calc_matrix_space_with_image_dims(snode, ar, sbeam_group->state.dims, gz->matrix_space);
}
-static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
Main *bmain = CTX_data_main(C);
- struct NodeSunBeamsWidgetGroup *sbeam_group = mgroup->customdata;
- wmGizmo *mpr = sbeam_group->gizmo;
+ struct NodeSunBeamsWidgetGroup *sbeam_group = gzgroup->customdata;
+ wmGizmo *gz = sbeam_group->gizmo;
void *lock;
Image *ima = BKE_image_verify_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
@@ -472,28 +472,28 @@ static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmGizmoGroup *mgro
/* need to set property here for undo. TODO would prefer to do this in _init */
PointerRNA nodeptr;
RNA_pointer_create((ID *)snode->edittree, &RNA_CompositorNodeSunBeams, node, &nodeptr);
- WM_gizmo_target_property_def_rna(mpr, "offset", &nodeptr, "source", -1);
+ WM_gizmo_target_property_def_rna(gz, "offset", &nodeptr, "source", -1);
- WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_MODAL, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_MODAL, true);
}
else {
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
}
BKE_image_release_ibuf(ima, ibuf, lock);
}
-void NODE_WGT_backdrop_sun_beams(wmGizmoGroupType *wgt)
+void NODE_GGT_backdrop_sun_beams(wmGizmoGroupType *gzgt)
{
- wgt->name = "Sun Beams Widget";
- wgt->idname = "NODE_WGT_sbeam";
+ gzgt->name = "Sun Beams Widget";
+ gzgt->idname = "NODE_GGT_sbeam";
- wgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT;
+ gzgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT;
- wgt->poll = WIDGETGROUP_node_sbeam_poll;
- wgt->setup = WIDGETGROUP_node_sbeam_setup;
- wgt->draw_prepare = WIDGETGROUP_node_sbeam_draw_prepare;
- wgt->refresh = WIDGETGROUP_node_sbeam_refresh;
+ gzgt->poll = WIDGETGROUP_node_sbeam_poll;
+ gzgt->setup = WIDGETGROUP_node_sbeam_setup;
+ gzgt->draw_prepare = WIDGETGROUP_node_sbeam_draw_prepare;
+ gzgt->refresh = WIDGETGROUP_node_sbeam_refresh;
}
/** \} */
@@ -513,7 +513,7 @@ struct NodeCornerPinWidgetGroup {
} state;
};
-static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -532,26 +532,26 @@ static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmGizmoGroupType
return false;
}
-static void WIDGETGROUP_node_corner_pin_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_node_corner_pin_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
struct NodeCornerPinWidgetGroup *cpin_group = MEM_mallocN(sizeof(struct NodeCornerPinWidgetGroup), __func__);
- const wmGizmoType *wt_grab_3d = WM_gizmotype_find("GIZMO_WT_grab_3d", false);
+ const wmGizmoType *gzt_grab_3d = WM_gizmotype_find("GIZMO_GT_grab_3d", false);
for (int i = 0; i < 4; i++) {
- cpin_group->gizmos[i] = WM_gizmo_new_ptr(wt_grab_3d, mgroup, NULL);
- wmGizmo *mpr = cpin_group->gizmos[i];
+ cpin_group->gizmos[i] = WM_gizmo_new_ptr(gzt_grab_3d, gzgroup, NULL);
+ wmGizmo *gz = cpin_group->gizmos[i];
- RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_CROSS_2D);
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_CROSS_2D);
- mpr->scale_basis = 0.01f;
+ gz->scale_basis = 0.01f;
}
- mgroup->customdata = cpin_group;
+ gzgroup->customdata = cpin_group;
}
-static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct NodeCornerPinWidgetGroup *cpin_group = mgroup->customdata;
+ struct NodeCornerPinWidgetGroup *cpin_group = gzgroup->customdata;
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
@@ -560,15 +560,15 @@ static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmGizmoG
node_gizmo_calc_matrix_space_with_image_dims(snode, ar, cpin_group->state.dims, matrix_space);
for (int i = 0; i < 4; i++) {
- wmGizmo *mpr = cpin_group->gizmos[i];
- copy_m4_m4(mpr->matrix_space, matrix_space);
+ wmGizmo *gz = cpin_group->gizmos[i];
+ copy_m4_m4(gz->matrix_space, matrix_space);
}
}
-static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
Main *bmain = CTX_data_main(C);
- struct NodeCornerPinWidgetGroup *cpin_group = mgroup->customdata;
+ struct NodeCornerPinWidgetGroup *cpin_group = gzgroup->customdata;
void *lock;
Image *ima = BKE_image_verify_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
@@ -585,37 +585,37 @@ static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmGizmoGroup
int i = 0;
for (bNodeSocket *sock = node->inputs.first; sock && i < 4; sock = sock->next) {
if (sock->type == SOCK_VECTOR) {
- wmGizmo *mpr = cpin_group->gizmos[i++];
+ wmGizmo *gz = cpin_group->gizmos[i++];
PointerRNA sockptr;
RNA_pointer_create((ID *)snode->edittree, &RNA_NodeSocket, sock, &sockptr);
- WM_gizmo_target_property_def_rna(mpr, "offset", &sockptr, "default_value", -1);
+ WM_gizmo_target_property_def_rna(gz, "offset", &sockptr, "default_value", -1);
- WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_MODAL, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_MODAL, true);
}
}
}
else {
for (int i = 0; i < 4; i++) {
- wmGizmo *mpr = cpin_group->gizmos[i];
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true);
+ wmGizmo *gz = cpin_group->gizmos[i];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
}
}
BKE_image_release_ibuf(ima, ibuf, lock);
}
-void NODE_WGT_backdrop_corner_pin(wmGizmoGroupType *wgt)
+void NODE_GGT_backdrop_corner_pin(wmGizmoGroupType *gzgt)
{
- wgt->name = "Corner Pin Widget";
- wgt->idname = "NODE_WGT_backdrop_corner_pin";
+ gzgt->name = "Corner Pin Widget";
+ gzgt->idname = "NODE_GGT_backdrop_corner_pin";
- wgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT;
+ gzgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT;
- wgt->poll = WIDGETGROUP_node_corner_pin_poll;
- wgt->setup = WIDGETGROUP_node_corner_pin_setup;
- wgt->draw_prepare = WIDGETGROUP_node_corner_pin_draw_prepare;
- wgt->refresh = WIDGETGROUP_node_corner_pin_refresh;
+ gzgt->poll = WIDGETGROUP_node_corner_pin_poll;
+ gzgt->setup = WIDGETGROUP_node_corner_pin_setup;
+ gzgt->draw_prepare = WIDGETGROUP_node_corner_pin_draw_prepare;
+ gzgt->refresh = WIDGETGROUP_node_corner_pin_refresh;
}
/** \} */
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 742c3975c8d..3644c8d09e6 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -224,11 +224,13 @@ void NODE_OT_viewer_border(struct wmOperatorType *ot);
void NODE_OT_clear_viewer_border(struct wmOperatorType *ot);
/* node_widgets.c */
-void NODE_WGT_backdrop_transform(struct wmGizmoGroupType *wgt);
-void NODE_WGT_backdrop_crop(struct wmGizmoGroupType *wgt);
-void NODE_WGT_backdrop_sun_beams(struct wmGizmoGroupType *wgt);
-void NODE_WGT_backdrop_corner_pin(struct wmGizmoGroupType *wgt);
+void NODE_GGT_backdrop_transform(struct wmGizmoGroupType *gzgt);
+void NODE_GGT_backdrop_crop(struct wmGizmoGroupType *gzgt);
+void NODE_GGT_backdrop_sun_beams(struct wmGizmoGroupType *gzgt);
+void NODE_GGT_backdrop_corner_pin(struct wmGizmoGroupType *gzgt);
+void NODE_OT_cryptomatte_layer_add(struct wmOperatorType *ot);
+void NODE_OT_cryptomatte_layer_remove(struct wmOperatorType *ot);
extern const char *node_context_dir[];
@@ -236,7 +238,7 @@ extern const char *node_context_dir[];
// nodes draw without dpi - the view zoom is flexible
#define HIDDEN_RAD (0.75f * U.widget_unit)
-#define BASIS_RAD (0.4f * U.widget_unit)
+#define BASIS_RAD (0.2f * U.widget_unit)
#define NODE_DYS (U.widget_unit / 2)
#define NODE_DY U.widget_unit
#define NODE_SOCKDY (0.08f * U.widget_unit)
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 2a585c42395..dccc999b2d1 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -129,6 +129,9 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_tree_socket_add);
WM_operatortype_append(NODE_OT_tree_socket_remove);
WM_operatortype_append(NODE_OT_tree_socket_move);
+
+ WM_operatortype_append(NODE_OT_cryptomatte_layer_add);
+ WM_operatortype_append(NODE_OT_cryptomatte_layer_remove);
}
void ED_operatormacros_node(void)
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 1149b910947..51ba3a62d1b 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -675,40 +675,31 @@ static void node_main_region_draw(const bContext *C, ARegion *ar)
/* ************* dropboxes ************* */
-static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
- if (drag->type == WM_DRAG_ID) {
- ID *id = drag->poin;
- if (GS(id->name) == ID_IM)
- return 1;
+ if (drag->type == WM_DRAG_PATH) {
+ return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)); /* rule might not work? */
}
- else if (drag->type == WM_DRAG_PATH) {
- if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)) /* rule might not work? */
- return 1;
+ else {
+ return WM_drag_ID(drag, ID_IM) != NULL;
}
- return 0;
}
-static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
- if (drag->type == WM_DRAG_ID) {
- ID *id = drag->poin;
- if (GS(id->name) == ID_MSK)
- return 1;
- }
- return 0;
+ return WM_drag_ID(drag, ID_MSK) != NULL;
}
static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = drag->poin;
+ ID *id = WM_drag_ID(drag, 0);
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = drag->poin;
+ ID *id = WM_drag_ID(drag, 0);
if (id) {
RNA_string_set(drop->ptr, "name", id->name + 2);
@@ -752,7 +743,7 @@ static void node_region_listener(
wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
wmNotifier *wmn, const Scene *UNUSED(scene))
{
- wmGizmoMap *mmap = ar->gizmo_map;
+ wmGizmoMap *gzmap = ar->gizmo_map;
/* context changes */
switch (wmn->category) {
@@ -762,13 +753,13 @@ static void node_region_listener(
ED_region_tag_redraw(ar);
break;
case ND_SPACE_NODE_VIEW:
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
break;
}
break;
case NC_SCREEN:
if (wmn->data == ND_LAYOUTSET || wmn->action == NA_EDITED) {
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
}
switch (wmn->data) {
case ND_ANIMPLAY:
@@ -784,13 +775,13 @@ static void node_region_listener(
case NC_SCENE:
ED_region_tag_redraw(ar);
if (wmn->data == ND_RENDER_RESULT) {
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
}
break;
case NC_NODE:
ED_region_tag_redraw(ar);
if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
}
break;
case NC_MATERIAL:
@@ -863,12 +854,12 @@ static int node_context(const bContext *C, const char *member, bContextDataResul
static void node_widgets(void)
{
/* create the widgetmap for the area here */
- wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure(
+ wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(
&(const struct wmGizmoMapType_Params){SPACE_NODE, RGN_TYPE_WINDOW});
- WM_gizmogrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_transform);
- WM_gizmogrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_crop);
- WM_gizmogrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_sun_beams);
- WM_gizmogrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_corner_pin);
+ WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_transform);
+ WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_crop);
+ WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_sun_beams);
+ WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_corner_pin);
}
static void node_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt
index 96d27c6fd89..796e8732fca 100644
--- a/source/blender/editors/space_outliner/CMakeLists.txt
+++ b/source/blender/editors/space_outliner/CMakeLists.txt
@@ -39,6 +39,7 @@ set(INC_SYS
set(SRC
outliner_collections.c
+ outliner_dragdrop.c
outliner_draw.c
outliner_edit.c
outliner_ops.c
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index ad94615a0d2..d4c85ce28bd 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -99,6 +99,24 @@ Collection *outliner_collection_from_tree_element(const TreeElement *te)
return NULL;
}
+TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata)
+{
+ struct ObjectsSelectedData *data = 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_addtail(&data->objects_selected_array, BLI_genericNodeN(te));
+
+ return TRAVERSE_CONTINUE;
+}
+
/* -------------------------------------------------------------------- */
/* Poll functions. */
@@ -138,8 +156,10 @@ static TreeTraversalAction collection_find_selected_to_add(TreeElement *te, void
static int collection_new_exec(bContext *C, wmOperator *op)
{
SpaceOops *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
struct CollectionNewData data = {
.error = false,
@@ -147,6 +167,8 @@ static int collection_new_exec(bContext *C, wmOperator *op)
};
if (RNA_boolean_get(op->ptr, "nested")) {
+ outliner_build_tree(bmain, scene, view_layer, soops, ar);
+
outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_find_selected_to_add, &data);
if (data.error) {
@@ -574,7 +596,7 @@ static TreeTraversalAction layer_collection_find_data_to_edit(TreeElement *te, v
return TRAVERSE_CONTINUE;
}
-static bool collections_view_layer_poll(bContext *C, bool include)
+static bool collections_view_layer_poll(bContext *C, bool clear, int flag)
{
/* Poll function so the right click menu show current state of selected collections. */
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -593,10 +615,10 @@ static bool collections_view_layer_poll(bContext *C, bool include)
GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- if (include && (lc->flag & LAYER_COLLECTION_EXCLUDE)) {
+ if (clear && (lc->flag & flag)) {
result = true;
}
- else if (!include && !(lc->flag & LAYER_COLLECTION_EXCLUDE)) {
+ else if (!clear && !(lc->flag & flag)) {
result = true;
}
}
@@ -605,27 +627,47 @@ static bool collections_view_layer_poll(bContext *C, bool include)
return result;
}
-static bool collections_exclude_poll(bContext *C)
+static bool collections_exclude_set_poll(bContext *C)
+{
+ return collections_view_layer_poll(C, false, LAYER_COLLECTION_EXCLUDE);
+}
+
+static bool collections_exclude_clear_poll(bContext *C)
{
- return collections_view_layer_poll(C, false);
+ return collections_view_layer_poll(C, true, LAYER_COLLECTION_EXCLUDE);
}
-static bool collections_include_poll(bContext *C)
+static bool collections_holdout_set_poll(bContext *C)
{
- return collections_view_layer_poll(C, true);
+ return collections_view_layer_poll(C, false, LAYER_COLLECTION_HOLDOUT);
}
-static void layer_collection_exclude_recursive_set(LayerCollection *lc)
+static bool collections_holdout_clear_poll(bContext *C)
+{
+ return collections_view_layer_poll(C, true, LAYER_COLLECTION_HOLDOUT);
+}
+
+static bool collections_indirect_only_set_poll(bContext *C)
+{
+ return collections_view_layer_poll(C, false, LAYER_COLLECTION_INDIRECT_ONLY);
+}
+
+static bool collections_indirect_only_clear_poll(bContext *C)
+{
+ return collections_view_layer_poll(C, true, LAYER_COLLECTION_INDIRECT_ONLY);
+}
+
+static void layer_collection_flag_recursive_set(LayerCollection *lc, int flag)
{
for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
- if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
- nlc->flag |= LAYER_COLLECTION_EXCLUDE;
+ if (lc->flag & flag) {
+ nlc->flag |= flag;
}
else {
- nlc->flag &= ~LAYER_COLLECTION_EXCLUDE;
+ nlc->flag &= ~flag;
}
- layer_collection_exclude_recursive_set(nlc);
+ layer_collection_flag_recursive_set(nlc, flag);
}
}
@@ -636,7 +678,10 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
struct CollectionEditData data = {.scene = scene, .soops = soops};
- bool include = STREQ(op->idname, "OUTLINER_OT_collection_include_set");
+ bool clear = strstr(op->idname, "clear") != NULL;
+ int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT :
+ strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY :
+ LAYER_COLLECTION_EXCLUDE;
data.collections_to_edit = BLI_gset_ptr_new(__func__);
@@ -647,14 +692,14 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op)
LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter);
if (!(lc->collection->flag & COLLECTION_IS_MASTER)) {
- if (include) {
- lc->flag &= ~LAYER_COLLECTION_EXCLUDE;
+ if (clear) {
+ lc->flag &= ~flag;
}
else {
- lc->flag |= LAYER_COLLECTION_EXCLUDE;
+ lc->flag |= flag;
}
- layer_collection_exclude_recursive_set(lc);
+ layer_collection_flag_recursive_set(lc, flag);
}
}
@@ -671,28 +716,88 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_exclude_set(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Exclude from View Layer";
+ ot->name = "Set Exclude";
ot->idname = "OUTLINER_OT_collection_exclude_set";
ot->description = "Exclude collection from the active view layer";
/* api callbacks */
ot->exec = collection_view_layer_exec;
- ot->poll = collections_exclude_poll;
+ ot->poll = collections_exclude_set_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-void OUTLINER_OT_collection_include_set(wmOperatorType *ot)
+void OUTLINER_OT_collection_exclude_clear(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Include in View Layer";
- ot->idname = "OUTLINER_OT_collection_include_set";
+ ot->name = "Clear Exclude";
+ ot->idname = "OUTLINER_OT_collection_exclude_clear";
ot->description = "Include collection in the active view layer";
/* api callbacks */
ot->exec = collection_view_layer_exec;
- ot->poll = collections_include_poll;
+ ot->poll = collections_exclude_clear_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_holdout_set(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Set Holdout";
+ ot->idname = "OUTLINER_OT_collection_holdout_set";
+ ot->description = "Mask collection in the active view layer";
+
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_holdout_set_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_holdout_clear(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Clear Holdout";
+ ot->idname = "OUTLINER_OT_collection_holdout_clear";
+ ot->description = "Clear masking of collection in the active view layer";
+
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_holdout_clear_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_indirect_only_set(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Set Indirect Only";
+ ot->idname = "OUTLINER_OT_collection_indirect_only_set";
+ ot->description = "Set collection to only contribute indirectly (through shadows and reflections) in the view layer";
+
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_indirect_only_set_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_indirect_only_clear(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Clear Indirect Only";
+ ot->idname = "OUTLINER_OT_collection_indirect_only_clear";
+ ot->description = "Clear collection contributing only indirectly in the view layer";
+
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_indirect_only_clear_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
new file mode 100644
index 00000000000..55b9a561503
--- /dev/null
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -0,0 +1,954 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2004 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_outliner/outliner_dragdrop.c
+ * \ingroup spoutliner
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_group_types.h"
+#include "DNA_material_types.h"
+#include "DNA_object_types.h"
+#include "DNA_space_types.h"
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+
+#include "BLT_translation.h"
+
+#include "BKE_collection.h"
+#include "BKE_context.h"
+#include "BKE_layer.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_report.h"
+#include "BKE_scene.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
+#include "ED_object.h"
+#include "ED_outliner.h"
+#include "ED_screen.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "GPU_state.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "outliner_intern.h"
+
+/* ******************** Drop Target Find *********************** */
+
+static TreeElement *outliner_dropzone_element(TreeElement *te, const float fmval[2], const bool children)
+{
+ if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) {
+ /* name and first icon */
+ if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend))
+ return te;
+ }
+ /* Not it. Let's look at its children. */
+ if (children && (TREESTORE(te)->flag & TSE_CLOSED) == 0 && (te->subtree.first)) {
+ for (te = te->subtree.first; te; te = te->next) {
+ TreeElement *te_valid = outliner_dropzone_element(te, fmval, children);
+ if (te_valid)
+ return te_valid;
+ }
+ }
+ return NULL;
+}
+
+/* Find tree element to drop into. */
+static TreeElement *outliner_dropzone_find(const SpaceOops *soops, const float fmval[2], const bool children)
+{
+ TreeElement *te;
+
+ for (te = soops->tree.first; te; te = te->next) {
+ TreeElement *te_valid = outliner_dropzone_element(te, fmval, children);
+ if (te_valid)
+ return te_valid;
+ }
+ return NULL;
+}
+
+static TreeElement *outliner_drop_find(bContext *C, const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ float fmval[2];
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+
+ return outliner_dropzone_find(soops, fmval, true);
+}
+
+static ID *outliner_ID_drop_find(bContext *C, const wmEvent *event, short idcode)
+{
+ TreeElement *te = outliner_drop_find(C, event);
+ TreeStoreElem *tselem = (te) ? TREESTORE(te) : NULL;
+
+ if (te && te->idcode == idcode && tselem->type == 0) {
+ return tselem->id;
+ }
+ else {
+ return NULL;
+ }
+}
+
+/* Find tree element to drop into, with additional before and after reorder support. */
+static TreeElement *outliner_drop_insert_find(
+ bContext *C, const wmEvent *event,
+ TreeElementInsertType *r_insert_type)
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
+ TreeElement *te_hovered;
+ float view_mval[2];
+
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
+ te_hovered = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]);
+
+ if (te_hovered) {
+ /* mouse hovers an element (ignoring x-axis), now find out how to insert the dragged item exactly */
+ const float margin = UI_UNIT_Y * (1.0f / 4);
+
+ if (view_mval[1] < (te_hovered->ys + margin)) {
+ if (TSELEM_OPEN(TREESTORE(te_hovered), soops)) {
+ /* inserting after a open item means we insert into it, but as first child */
+ if (BLI_listbase_is_empty(&te_hovered->subtree)) {
+ *r_insert_type = TE_INSERT_INTO;
+ return te_hovered;
+ }
+ else {
+ *r_insert_type = TE_INSERT_BEFORE;
+ return te_hovered->subtree.first;
+ }
+ }
+ else {
+ *r_insert_type = TE_INSERT_AFTER;
+ return te_hovered;
+ }
+ }
+ else if (view_mval[1] > (te_hovered->ys + (3 * margin))) {
+ *r_insert_type = TE_INSERT_BEFORE;
+ return te_hovered;
+ }
+ else {
+ *r_insert_type = TE_INSERT_INTO;
+ return te_hovered;
+ }
+ }
+ else {
+ /* mouse doesn't hover any item (ignoring x-axis), so it's either above list bounds or below. */
+ TreeElement *first = soops->tree.first;
+ TreeElement *last = soops->tree.last;
+
+ if (view_mval[1] < last->ys) {
+ *r_insert_type = TE_INSERT_AFTER;
+ return last;
+ }
+ else if (view_mval[1] > (first->ys + UI_UNIT_Y)) {
+ *r_insert_type = TE_INSERT_BEFORE;
+ return first;
+ }
+ else {
+ BLI_assert(0);
+ return NULL;
+ }
+ }
+}
+
+static TreeElement *outliner_drop_insert_collection_find(
+ bContext *C, const wmEvent *event,
+ TreeElementInsertType *r_insert_type)
+{
+ TreeElement *te = outliner_drop_insert_find(C, event, r_insert_type);
+ if (!te) {
+ return NULL;
+ }
+
+ Collection *collection = outliner_collection_from_tree_element(te);
+ if (!collection) {
+ return NULL;
+ }
+
+ /* We can't insert/before after master collection. */
+ if (collection->flag & COLLECTION_IS_MASTER) {
+ if (*r_insert_type == TE_INSERT_BEFORE) {
+ /* can't go higher than master collection, insert into it */
+ *r_insert_type = TE_INSERT_INTO;
+ }
+ else if (*r_insert_type == TE_INSERT_AFTER) {
+ te = te->subtree.last;
+ collection = outliner_collection_from_tree_element(te);
+ if (!collection) {
+ return NULL;
+ }
+ }
+ }
+
+ return te;
+}
+
+/* ******************** Parent Drop Operator *********************** */
+
+static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip))
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ Object *ob = (Object *)WM_drag_ID(drag, ID_OB);
+ if (!ob) {
+ return false;
+ }
+
+ /* Ensure item under cursor is valid drop target */
+ TreeElement *te = outliner_drop_find(C, event);
+ TreeStoreElem *tselem = te ? TREESTORE(te) : NULL;
+
+ if (!te) {
+ /* pass */
+ }
+ else if (te->idcode == ID_OB && tselem->type == 0) {
+ Scene *scene;
+ ID *te_id = tselem->id;
+
+ /* check if dropping self or parent */
+ if (te_id == &ob->id || (Object *)te_id == ob->parent)
+ return false;
+
+ /* check that parent/child are both in the same scene */
+ scene = (Scene *)outliner_search_back(soops, te, ID_SCE);
+
+ /* currently outliner organized in a way that if there's no parent scene
+ * element for object it means that all displayed objects belong to
+ * active scene and parenting them is allowed (sergey)
+ */
+ if (!scene) {
+ return true;
+ }
+ else {
+ for (ViewLayer *view_layer = scene->view_layers.first;
+ view_layer;
+ view_layer = view_layer->next)
+ {
+ if (BKE_view_layer_base_find(view_layer, ob)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static int parent_drop_exec(bContext *C, wmOperator *op)
+{
+ Object *par = NULL, *ob = NULL;
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ int partype = -1;
+ char parname[MAX_ID_NAME], childname[MAX_ID_NAME];
+
+ partype = RNA_enum_get(op->ptr, "type");
+ RNA_string_get(op->ptr, "parent", parname);
+ par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname);
+ RNA_string_get(op->ptr, "child", childname);
+ ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname);
+
+ if (ID_IS_LINKED(ob)) {
+ BKE_report(op->reports, RPT_INFO, "Can't edit library linked object");
+ return OPERATOR_CANCELLED;
+ }
+
+ ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL);
+
+ DEG_relations_tag_update(bmain);
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Main *bmain = CTX_data_main(C);
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ TreeElement *te = outliner_drop_find(C, event);
+ TreeStoreElem *tselem = te ? TREESTORE(te) : NULL;
+
+ if (!(te && te->idcode == ID_OB && tselem->type == 0)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ Object *par = (Object *)tselem->id;
+ Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB);
+
+ if (ELEM(NULL, ob, par)) {
+ return OPERATOR_CANCELLED;
+ }
+ if (ob == par) {
+ return OPERATOR_CANCELLED;
+ }
+ if (ID_IS_LINKED(ob)) {
+ BKE_report(op->reports, RPT_INFO, "Can't edit library linked object");
+ return OPERATOR_CANCELLED;
+ }
+
+ char childname[MAX_ID_NAME];
+ char parname[MAX_ID_NAME];
+ STRNCPY(childname, ob->id.name);
+ STRNCPY(parname, par->id.name);
+ RNA_string_set(op->ptr, "child", childname);
+ RNA_string_set(op->ptr, "parent", parname);
+
+ Scene *scene = (Scene *)outliner_search_back(soops, te, ID_SCE);
+
+ if (scene == NULL) {
+ /* currently outlier organized in a way, that if there's no parent scene
+ * element for object it means that all displayed objects belong to
+ * active scene and parenting them is allowed (sergey)
+ */
+
+ scene = CTX_data_scene(C);
+ }
+
+ if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) {
+ int partype = 0;
+ if (ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL)) {
+ DEG_relations_tag_update(bmain);
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
+ }
+ }
+ else {
+ /* Menu creation */
+ wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+ PointerRNA ptr;
+
+ /* Cannot use uiItemEnumO()... have multiple properties to set. */
+ uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_OBJECT);
+
+ /* par becomes parent, make the associated menus */
+ if (par->type == OB_ARMATURE) {
+ uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_ARMATURE);
+
+ uiItemFullO_ptr(layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME);
+
+ uiItemFullO_ptr(layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE);
+
+ uiItemFullO_ptr(layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO);
+
+ uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_BONE);
+ }
+ else if (par->type == OB_CURVE) {
+ uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_CURVE);
+
+ uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_FOLLOW);
+
+ uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_PATH_CONST);
+ }
+ else if (par->type == OB_LATTICE) {
+ uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_LATTICE);
+ }
+
+ UI_popup_menu_end(C, pup);
+
+ return OPERATOR_INTERFACE;
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_parent_drop(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Drop to Set Parent";
+ ot->description = "Drag to parent in Outliner";
+ ot->idname = "OUTLINER_OT_parent_drop";
+
+ /* api callbacks */
+ ot->invoke = parent_drop_invoke;
+ ot->exec = parent_drop_exec;
+
+ ot->poll = ED_operator_outliner_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+
+ /* properties */
+ RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object");
+ RNA_def_string(ot->srna, "parent", "Object", MAX_ID_NAME, "Parent", "Parent Object");
+ RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
+}
+
+static bool parenting_poll(bContext *C)
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+
+ if (soops) {
+ if (soops->outlinevis == SO_SCENES) {
+ return true;
+ }
+ else if ((soops->outlinevis == SO_VIEW_LAYER) &&
+ (soops->filter & SO_FILTER_NO_COLLECTION))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* ******************** Parent Clear Operator *********************** */
+
+static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip))
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+
+ if (!ELEM(soops->outlinevis, SO_VIEW_LAYER)) {
+ return false;
+ }
+
+ Object *ob = (Object *)WM_drag_ID(drag, ID_OB);
+ if (!(ob && ob->parent)) {
+ return false;
+ }
+
+ TreeElement *te = outliner_drop_find(C, event);
+ if (te) {
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ switch (te->idcode) {
+ case ID_SCE:
+ return (ELEM(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER));
+ case ID_OB:
+ return (ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE));
+ /* Other codes to ignore? */
+ }
+ }
+ return (te == NULL);
+}
+
+static int parent_clear_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB);
+
+ if (ob == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ ED_object_parent_clear(ob, 0);
+
+ DEG_relations_tag_update(bmain);
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_parent_clear(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Drop to Clear Parent";
+ ot->description = "Drag to clear parent in Outliner";
+ ot->idname = "OUTLINER_OT_parent_clear";
+
+ /* api callbacks */
+ ot->invoke = parent_clear_invoke;
+
+ ot->poll = parenting_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
+/* ******************** Scene Drop Operator *********************** */
+
+static bool scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip))
+{
+ /* Ensure item under cursor is valid drop target */
+ Object *ob = (Object *)WM_drag_ID(drag, ID_OB);
+ return (ob && (outliner_ID_drop_find(C, event, ID_SCE) != NULL));
+}
+
+static int scene_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = (Scene *)outliner_ID_drop_find(C, event, ID_SCE);
+ Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB);
+
+ if (ELEM(NULL, ob, scene) || ID_IS_LINKED(scene)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (BKE_scene_has_object(scene, ob)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ Collection *collection;
+ if (scene != CTX_data_scene(C)) {
+ /* when linking to an inactive scene link to the master collection */
+ collection = BKE_collection_master(scene);
+ }
+ else {
+ collection = CTX_data_collection(C);
+ }
+
+ BKE_collection_object_add(bmain, collection, ob);
+
+ for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ if (base) {
+ ED_object_base_select(base, BA_SELECT);
+ }
+ }
+
+ DEG_relations_tag_update(bmain);
+
+ DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE);
+ WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_scene_drop(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Drop Object to Scene";
+ ot->description = "Drag object to scene in Outliner";
+ ot->idname = "OUTLINER_OT_scene_drop";
+
+ /* api callbacks */
+ ot->invoke = scene_drop_invoke;
+
+ ot->poll = ED_operator_outliner_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
+/* ******************** Material Drop Operator *********************** */
+
+static bool material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip))
+{
+ /* Ensure item under cursor is valid drop target */
+ Material *ma = (Material *)WM_drag_ID(drag, ID_MA);
+ return (ma && (outliner_ID_drop_find(C, event, ID_OB) != NULL));
+}
+
+static int material_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob = (Object *)outliner_ID_drop_find(C, event, ID_OB);
+ Material *ma = (Material *)WM_drag_ID_from_event(event, ID_MA);
+
+ if (ELEM(NULL, ob, ma)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ assign_material(bmain, ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
+
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
+
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_material_drop(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Drop Material on Object";
+ ot->description = "Drag material to object in Outliner";
+ ot->idname = "OUTLINER_OT_material_drop";
+
+ /* api callbacks */
+ ot->invoke = material_drop_invoke;
+
+ ot->poll = ED_operator_outliner_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
+/* ******************** Collection Drop Operator *********************** */
+
+typedef struct CollectionDrop {
+ Collection *from;
+ Collection *to;
+
+ TreeElement *te;
+ TreeElementInsertType insert_type;
+} CollectionDrop;
+
+static Collection *collection_parent_from_ID(ID *id)
+{
+ /* Can't change linked parent collections. */
+ if (!id || ID_IS_LINKED(id)) {
+ return NULL;
+ }
+
+ /* Also support dropping into/from scene collection. */
+ if (GS(id->name) == ID_SCE) {
+ return ((Scene *)id)->master_collection;
+ }
+ else if (GS(id->name) == ID_GR) {
+ return (Collection *)id;
+ }
+
+ return NULL;
+}
+
+static bool collection_drop_init(bContext *C, wmDrag *drag, const wmEvent *event, CollectionDrop *data)
+{
+ /* Get collection to drop into. */
+ TreeElementInsertType insert_type;
+ TreeElement *te = outliner_drop_insert_collection_find(C, event, &insert_type);
+ if (!te) {
+ return false;
+ }
+
+ Collection *to_collection = outliner_collection_from_tree_element(te);
+ if (ID_IS_LINKED(to_collection)) {
+ return false;
+ }
+
+ /* Get drag datablocks. */
+ if (drag->type != WM_DRAG_ID) {
+ return false;
+ }
+
+ wmDragID *drag_id = drag->ids.first;
+ if (drag_id == NULL) {
+ return false;
+ }
+
+ ID *id = drag_id->id;
+ if (!(id && ELEM(GS(id->name), ID_GR, ID_OB))) {
+ return false;
+ }
+
+ /* Get collection to drag out of. */
+ ID *parent = drag_id->from_parent;
+ Collection *from_collection = collection_parent_from_ID(parent);
+ if (event->ctrl) {
+ from_collection = NULL;
+ }
+
+ /* Get collections. */
+ if (GS(id->name) == ID_GR) {
+ if (id == &to_collection->id) {
+ return false;
+ }
+ }
+ else {
+ insert_type = TE_INSERT_INTO;
+ }
+
+ data->from = from_collection;
+ data->to = to_collection;
+ data->te = te;
+ data->insert_type = insert_type;
+
+ return true;
+}
+
+static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **tooltip)
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
+ bool changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false);
+
+ CollectionDrop data;
+ if (collection_drop_init(C, drag, event, &data)) {
+ if (!data.from || event->ctrl) {
+ *tooltip = IFACE_("Link inside Collection");
+ }
+ else {
+ TreeElement *te = data.te;
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ switch (data.insert_type) {
+ case TE_INSERT_BEFORE:
+ tselem->flag |= TSE_DRAG_BEFORE;
+ changed = true;
+ if (te->prev && outliner_is_collection_tree_element(te->prev)) {
+ *tooltip = TIP_("Move between collections");
+ }
+ else {
+ *tooltip = TIP_("Move before collection");
+ }
+ break;
+ case TE_INSERT_AFTER:
+ tselem->flag |= TSE_DRAG_AFTER;
+ changed = true;
+ if (te->next && outliner_is_collection_tree_element(te->next)) {
+ *tooltip = TIP_("Move between collections");
+ }
+ else {
+ *tooltip = TIP_("Move after collection");
+ }
+ break;
+ case TE_INSERT_INTO:
+ tselem->flag |= TSE_DRAG_INTO;
+ changed = true;
+ *tooltip = TIP_("Move inside collection (Ctrl to link)");
+ break;
+ }
+ }
+ }
+
+ if (changed) {
+ ED_region_tag_redraw_no_rebuild(ar);
+ }
+
+ return true;
+}
+
+static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+
+ if (event->custom != EVT_DATA_DRAGDROP) {
+ return OPERATOR_CANCELLED;
+ }
+
+ ListBase *lb = event->customdata;
+ wmDrag *drag = lb->first;
+
+ CollectionDrop data;
+ if (!collection_drop_init(C, drag, event, &data)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Before/after insert handling. */
+ Collection *relative = NULL;
+ bool relative_after = false;
+
+ if (ELEM(data.insert_type, TE_INSERT_BEFORE, TE_INSERT_AFTER)) {
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+
+ relative = data.to;
+ relative_after = (data.insert_type == TE_INSERT_AFTER);
+
+ TreeElement *parent_te = outliner_find_parent_element(&soops->tree, NULL, data.te);
+ data.to = (parent_te) ? outliner_collection_from_tree_element(parent_te) : NULL;
+ }
+
+ if (!data.to) {
+ return OPERATOR_CANCELLED;
+ }
+
+ for (wmDragID *drag_id = drag->ids.first; drag_id; drag_id = drag_id->next) {
+ /* Ctrl enables linking, so we don't need a from collection then. */
+ Collection *from = (event->ctrl) ? NULL : collection_parent_from_ID(drag_id->from_parent);
+
+ if (GS(drag_id->id->name) == ID_OB) {
+ /* Move/link object into collection. */
+ Object *object = (Object *)drag_id->id;
+
+ if (from) {
+ BKE_collection_object_move(bmain, scene, data.to, from, object);
+ }
+ else {
+ BKE_collection_object_add(bmain, data.to, object);
+ }
+ }
+ else if (GS(drag_id->id->name) == ID_GR) {
+ /* Move/link collection into collection. */
+ Collection *collection = (Collection *)drag_id->id;
+
+ if (collection != from) {
+ BKE_collection_move(bmain, data.to, from, relative, relative_after, collection);
+ }
+ }
+
+ if (from) {
+ DEG_id_tag_update(&from->id, DEG_TAG_COPY_ON_WRITE);
+ }
+ }
+
+ /* Update dependency graph. */
+ DEG_id_tag_update(&data.to->id, DEG_TAG_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_collection_drop(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Move to Collection";
+ ot->description = "Drag to move to collection in Outliner";
+ ot->idname = "OUTLINER_OT_collection_drop";
+
+ /* api callbacks */
+ ot->invoke = collection_drop_invoke;
+ ot->poll = ED_operator_outliner_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
+/* ********************* Outliner Drag Operator ******************** */
+
+static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event)
+{
+ /* note: using EVT_TWEAK_ events to trigger dragging is fine,
+ * it sends coordinates from where dragging was started */
+ const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
+ return outliner_find_item_at_y(soops, &soops->tree, my);
+}
+
+static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ TreeElement *te = outliner_item_drag_element_find(soops, ar, event);
+
+ if (!te) {
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ TreeElementIcon data = tree_element_get_icon(TREESTORE(te), te);
+ if (!data.drag_id) {
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ wmDrag *drag = WM_event_start_drag(C, data.icon, WM_DRAG_ID, NULL, 0.0, WM_DRAG_NOP);
+
+ if (GS(data.drag_id->name) == ID_OB) {
+ /* For objects we cheat and drag all selected objects. */
+ TREESTORE(te)->flag |= TSE_SELECTED;
+
+ struct ObjectsSelectedData selected = {
+ .objects_selected_array = {NULL, NULL},
+ };
+
+ outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &selected);
+ LISTBASE_FOREACH (LinkData *, link, &selected.objects_selected_array) {
+ TreeElement *ten_selected = (TreeElement *)link->data;
+ Object *ob = (Object *)TREESTORE(ten_selected)->id;
+
+ /* Find parent collection of object. */
+ Collection *parent = NULL;
+
+ if (ten_selected->parent) {
+ for (TreeElement *te_ob_parent = ten_selected->parent; te_ob_parent; te_ob_parent = te_ob_parent->parent) {
+ if (outliner_is_collection_tree_element(te_ob_parent)) {
+ parent = outliner_collection_from_tree_element(te_ob_parent);
+ break;
+ }
+ }
+ }
+ else {
+ Scene *scene = CTX_data_scene(C);
+ parent = BKE_collection_master(scene);
+ }
+
+ WM_drag_add_ID(drag, &ob->id, &parent->id);
+ }
+
+ BLI_freelistN(&selected.objects_selected_array);
+ }
+ else {
+ /* Add single ID. */
+ WM_drag_add_ID(drag, data.drag_id, data.drag_parent);
+ }
+
+ return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
+}
+
+/* Outliner drag and drop. This operator mostly exists to support dragging
+ * from outliner text instead of only from the icon, and also to show a
+ * hint in the statusbar keymap. */
+
+void OUTLINER_OT_item_drag_drop(wmOperatorType *ot)
+{
+ ot->name = "Drag and Drop";
+ ot->idname = "OUTLINER_OT_item_drag_drop";
+ ot->description = "Drag and drop element to another place";
+
+ ot->invoke = outliner_item_drag_drop_invoke;
+ ot->poll = ED_operator_outliner_active;
+}
+
+/* *************************** Drop Boxes ************************** */
+
+/* region dropbox definition */
+void outliner_dropboxes(void)
+{
+ ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
+
+ WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, NULL);
+ WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL);
+ WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL);
+ WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL);
+ WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, NULL);
+}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 8e111beec54..5244c364b80 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -32,6 +32,7 @@
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_gpencil_modifier_types.h"
#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lightprobe_types.h"
@@ -50,6 +51,7 @@
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_fcurve.h"
+#include "BKE_gpencil.h"
#include "BKE_global.h"
#include "BKE_idcode.h"
#include "BKE_layer.h"
@@ -438,12 +440,16 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
}
case TSE_GP_LAYER:
{
- bGPdata *gpd = (bGPdata *)tselem->id; // id = GP Datablock
+ bGPdata *gpd = (bGPdata *)tselem->id; /* id = GP Datablock */
bGPDlayer *gpl = te->directdata;
+ /* always make layer active */
+ BKE_gpencil_layer_setactive(gpd, gpl);
+
// XXX: name needs translation stuff
BLI_uniquename(&gpd->layers, gpl, "GP Layer", '.',
offsetof(bGPDlayer, info), sizeof(gpl->info));
+
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, gpd);
break;
}
@@ -742,11 +748,11 @@ static void outliner_draw_rnacols(ARegion *ar, int sizex)
GPU_line_width(1.0f);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShadeAlpha(TH_BACK, -15, -200);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, sizex, v2d->cur.ymax);
immVertex2f(pos, sizex, miny);
@@ -844,394 +850,389 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Tre
/* ****************************************************** */
/* Normal Drawing... */
-/* make function calls a bit compacter */
-struct DrawIconArg {
- uiBlock *block;
- ID *id;
- float xmax, x, y, xb, yb;
- float alpha;
-};
-
-static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
+TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
{
- /* restrict column clip... it has been coded by simply overdrawing, doesnt work for buttons */
- if (arg->x >= arg->xmax) {
- GPU_blend(true);
- UI_icon_draw_alpha(arg->x, arg->y, icon, arg->alpha);
- GPU_blend(false);
- }
- else {
- uiBut *but = uiDefIconBut(
- arg->block, UI_BTYPE_LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL,
- 0.0, 0.0, 1.0, arg->alpha,
- (arg->id && ID_IS_LINKED(arg->id)) ? arg->id->lib->name : "");
-
- if (arg->id)
- UI_but_drag_set_id(but, arg->id);
- }
-
-}
-
-static void UNUSED_FUNCTION(tselem_draw_gp_icon_uibut)(struct DrawIconArg *arg, ID *id, bGPDlayer *gpl)
-{
- /* restrict column clip - skip it for now... */
- if (arg->x >= arg->xmax) {
- /* pass */
- }
- else {
- PointerRNA ptr;
- const float eps = 0.001f;
- const bool is_stroke_visible = (gpl->color[3] > eps);
- const bool is_fill_visible = (gpl->fill[3] > eps);
- float w = 0.5f * UI_UNIT_X;
- float h = 0.85f * UI_UNIT_Y;
-
- RNA_pointer_create(id, &RNA_GPencilLayer, gpl, &ptr);
-
- UI_block_align_begin(arg->block);
-
- UI_block_emboss_set(arg->block, is_stroke_visible ? UI_EMBOSS : UI_EMBOSS_NONE);
- uiDefButR(arg->block, UI_BTYPE_COLOR, 1, "", arg->xb, arg->yb, w, h,
- &ptr, "color", -1,
- 0, 0, 0, 0, NULL);
-
- UI_block_emboss_set(arg->block, is_fill_visible ? UI_EMBOSS : UI_EMBOSS_NONE);
- uiDefButR(arg->block, UI_BTYPE_COLOR, 1, "", arg->xb + w, arg->yb, w, h,
- &ptr, "fill_color", -1,
- 0, 0, 0, 0, NULL);
-
- UI_block_emboss_set(arg->block, UI_EMBOSS_NONE);
- UI_block_align_end(arg->block);
- }
-}
-
-static void tselem_draw_icon(
- uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te,
- float alpha, const bool is_clickable)
-{
- struct DrawIconArg arg;
- float aspect;
-
- /* make function calls a bit compacter */
- arg.block = block;
- arg.id = tselem->id;
- arg.xmax = xmax;
- arg.xb = x; /* for ui buttons */
- arg.yb = y;
- arg.alpha = alpha;
-
- /* placement of icons, copied from interface_widgets.c */
- aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
- x += 2.0f * aspect;
- y += 2.0f * aspect;
- arg.x = x;
- arg.y = y;
-
-#define ICON_DRAW(_icon) UI_icon_draw_alpha(x, y, _icon, alpha)
-#define ICON_CLICK_DRAW(_icon) if (!is_clickable) ICON_DRAW(_icon); else tselem_draw_icon_uibut(&arg, _icon)
+ TreeElementIcon data = {0};
if (tselem->type) {
switch (tselem->type) {
case TSE_ANIM_DATA:
- ICON_DRAW(ICON_ANIM_DATA); /* XXX */
+ data.icon = ICON_ANIM_DATA; /* XXX */
break;
case TSE_NLA:
- ICON_DRAW(ICON_NLA);
+ data.icon = ICON_NLA;
break;
case TSE_NLA_TRACK:
- ICON_DRAW(ICON_NLA); /* XXX */
+ data.icon = ICON_NLA; /* XXX */
break;
case TSE_NLA_ACTION:
- ICON_DRAW(ICON_ACTION);
+ data.icon = ICON_ACTION;
break;
case TSE_DRIVER_BASE:
- ICON_DRAW(ICON_DRIVER);
+ data.icon = ICON_DRIVER;
break;
case TSE_DEFGROUP_BASE:
- ICON_DRAW(ICON_GROUP_VERTEX);
+ data.icon = ICON_GROUP_VERTEX;
break;
case TSE_BONE:
case TSE_EBONE:
- ICON_DRAW(ICON_BONE_DATA);
+ data.icon = ICON_BONE_DATA;
break;
case TSE_CONSTRAINT_BASE:
- ICON_DRAW(ICON_CONSTRAINT);
+ data.icon = ICON_CONSTRAINT;
break;
case TSE_MODIFIER_BASE:
- ICON_DRAW(ICON_MODIFIER);
+ data.icon = ICON_MODIFIER;
break;
case TSE_LINKED_OB:
- ICON_DRAW(ICON_OBJECT_DATA);
+ data.icon = ICON_OBJECT_DATA;
break;
case TSE_LINKED_PSYS:
- ICON_DRAW(ICON_PARTICLES);
+ data.icon = ICON_PARTICLES;
break;
case TSE_MODIFIER:
{
Object *ob = (Object *)tselem->id;
- ModifierData *md = BLI_findlink(&ob->modifiers, tselem->nr);
- switch ((ModifierType)md->type) {
- case eModifierType_Subsurf:
- ICON_DRAW(ICON_MOD_SUBSURF);
- break;
- case eModifierType_Armature:
- ICON_DRAW(ICON_MOD_ARMATURE);
- break;
- case eModifierType_Lattice:
- ICON_DRAW(ICON_MOD_LATTICE);
- break;
- case eModifierType_Curve:
- ICON_DRAW(ICON_MOD_CURVE);
- break;
- case eModifierType_Build:
- ICON_DRAW(ICON_MOD_BUILD);
- break;
- case eModifierType_Mirror:
- ICON_DRAW(ICON_MOD_MIRROR);
- break;
- case eModifierType_Decimate:
- ICON_DRAW(ICON_MOD_DECIM);
- break;
- case eModifierType_Wave:
- ICON_DRAW(ICON_MOD_WAVE);
- break;
- case eModifierType_Hook:
- ICON_DRAW(ICON_HOOK);
- break;
- case eModifierType_Softbody:
- ICON_DRAW(ICON_MOD_SOFT);
- break;
- case eModifierType_Boolean:
- ICON_DRAW(ICON_MOD_BOOLEAN);
- break;
- case eModifierType_ParticleSystem:
- ICON_DRAW(ICON_MOD_PARTICLES);
- break;
- case eModifierType_ParticleInstance:
- ICON_DRAW(ICON_MOD_PARTICLES);
- break;
- case eModifierType_EdgeSplit:
- ICON_DRAW(ICON_MOD_EDGESPLIT);
- break;
- case eModifierType_Array:
- ICON_DRAW(ICON_MOD_ARRAY);
- break;
- case eModifierType_UVProject:
- case eModifierType_UVWarp: /* TODO, get own icon */
- ICON_DRAW(ICON_MOD_UVPROJECT);
- break;
- case eModifierType_Displace:
- ICON_DRAW(ICON_MOD_DISPLACE);
- break;
- case eModifierType_Shrinkwrap:
- ICON_DRAW(ICON_MOD_SHRINKWRAP);
- break;
- case eModifierType_Cast:
- ICON_DRAW(ICON_MOD_CAST);
- break;
- case eModifierType_MeshDeform:
- case eModifierType_SurfaceDeform:
- ICON_DRAW(ICON_MOD_MESHDEFORM);
- break;
- case eModifierType_Bevel:
- ICON_DRAW(ICON_MOD_BEVEL);
- break;
- case eModifierType_Smooth:
- case eModifierType_LaplacianSmooth:
- case eModifierType_CorrectiveSmooth:
- ICON_DRAW(ICON_MOD_SMOOTH);
- break;
- case eModifierType_SimpleDeform:
- ICON_DRAW(ICON_MOD_SIMPLEDEFORM);
- break;
- case eModifierType_Mask:
- ICON_DRAW(ICON_MOD_MASK);
- break;
- case eModifierType_Cloth:
- ICON_DRAW(ICON_MOD_CLOTH);
- break;
- case eModifierType_Explode:
- ICON_DRAW(ICON_MOD_EXPLODE);
- break;
- case eModifierType_Collision:
- case eModifierType_Surface:
- ICON_DRAW(ICON_MOD_PHYSICS);
- break;
- case eModifierType_Fluidsim:
- ICON_DRAW(ICON_MOD_FLUIDSIM);
- break;
- case eModifierType_Multires:
- ICON_DRAW(ICON_MOD_MULTIRES);
- break;
- case eModifierType_Smoke:
- ICON_DRAW(ICON_MOD_SMOKE);
- break;
- case eModifierType_Solidify:
- ICON_DRAW(ICON_MOD_SOLIDIFY);
- break;
- case eModifierType_Screw:
- ICON_DRAW(ICON_MOD_SCREW);
- break;
- case eModifierType_Remesh:
- ICON_DRAW(ICON_MOD_REMESH);
- break;
- case eModifierType_WeightVGEdit:
- case eModifierType_WeightVGMix:
- case eModifierType_WeightVGProximity:
- ICON_DRAW(ICON_MOD_VERTEX_WEIGHT);
- break;
- case eModifierType_DynamicPaint:
- ICON_DRAW(ICON_MOD_DYNAMICPAINT);
- break;
- case eModifierType_Ocean:
- ICON_DRAW(ICON_MOD_OCEAN);
- break;
- case eModifierType_Warp:
- ICON_DRAW(ICON_MOD_WARP);
- break;
- case eModifierType_Skin:
- ICON_DRAW(ICON_MOD_SKIN);
- break;
- case eModifierType_Triangulate:
- ICON_DRAW(ICON_MOD_TRIANGULATE);
- break;
- case eModifierType_MeshCache:
- ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */
- break;
- case eModifierType_MeshSequenceCache:
- ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */
- break;
- case eModifierType_Wireframe:
- ICON_DRAW(ICON_MOD_WIREFRAME);
- break;
- case eModifierType_LaplacianDeform:
- ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */
- break;
- case eModifierType_DataTransfer:
- ICON_DRAW(ICON_MOD_DATA_TRANSFER);
- break;
- case eModifierType_NormalEdit:
- ICON_DRAW(ICON_MOD_NORMALEDIT);
- break;
- case eModifierType_Hair:
- ICON_DRAW(ICON_STRANDS);
- break;
- /* Default */
- case eModifierType_None:
- case eModifierType_ShapeKey:
- case NUM_MODIFIER_TYPES:
- ICON_DRAW(ICON_DOT);
- break;
+ if (ob->type != OB_GPENCIL) {
+ ModifierData *md = BLI_findlink(&ob->modifiers, tselem->nr);
+ switch ((ModifierType)md->type) {
+ case eModifierType_Subsurf:
+ data.icon = ICON_MOD_SUBSURF;
+ break;
+ case eModifierType_Armature:
+ data.icon = ICON_MOD_ARMATURE;
+ break;
+ case eModifierType_Lattice:
+ data.icon = ICON_MOD_LATTICE;
+ break;
+ case eModifierType_Curve:
+ data.icon = ICON_MOD_CURVE;
+ break;
+ case eModifierType_Build:
+ data.icon = ICON_MOD_BUILD;
+ break;
+ case eModifierType_Mirror:
+ data.icon = ICON_MOD_MIRROR;
+ break;
+ case eModifierType_Decimate:
+ data.icon = ICON_MOD_DECIM;
+ break;
+ case eModifierType_Wave:
+ data.icon = ICON_MOD_WAVE;
+ break;
+ case eModifierType_Hook:
+ data.icon = ICON_HOOK;
+ break;
+ case eModifierType_Softbody:
+ data.icon = ICON_MOD_SOFT;
+ break;
+ case eModifierType_Boolean:
+ data.icon = ICON_MOD_BOOLEAN;
+ break;
+ case eModifierType_ParticleSystem:
+ data.icon = ICON_MOD_PARTICLES;
+ break;
+ case eModifierType_ParticleInstance:
+ data.icon = ICON_MOD_PARTICLES;
+ break;
+ case eModifierType_EdgeSplit:
+ data.icon = ICON_MOD_EDGESPLIT;
+ break;
+ case eModifierType_Array:
+ data.icon = ICON_MOD_ARRAY;
+ break;
+ case eModifierType_UVProject:
+ case eModifierType_UVWarp: /* TODO, get own icon */
+ data.icon = ICON_MOD_UVPROJECT;
+ break;
+ case eModifierType_Displace:
+ data.icon = ICON_MOD_DISPLACE;
+ break;
+ case eModifierType_Shrinkwrap:
+ data.icon = ICON_MOD_SHRINKWRAP;
+ break;
+ case eModifierType_Cast:
+ data.icon = ICON_MOD_CAST;
+ break;
+ case eModifierType_MeshDeform:
+ case eModifierType_SurfaceDeform:
+ data.icon = ICON_MOD_MESHDEFORM;
+ break;
+ case eModifierType_Bevel:
+ data.icon = ICON_MOD_BEVEL;
+ break;
+ case eModifierType_Smooth:
+ case eModifierType_LaplacianSmooth:
+ case eModifierType_CorrectiveSmooth:
+ data.icon = ICON_MOD_SMOOTH;
+ break;
+ case eModifierType_SimpleDeform:
+ data.icon = ICON_MOD_SIMPLEDEFORM;
+ break;
+ case eModifierType_Mask:
+ data.icon = ICON_MOD_MASK;
+ break;
+ case eModifierType_Cloth:
+ data.icon = ICON_MOD_CLOTH;
+ break;
+ case eModifierType_Explode:
+ data.icon = ICON_MOD_EXPLODE;
+ break;
+ case eModifierType_Collision:
+ case eModifierType_Surface:
+ data.icon = ICON_MOD_PHYSICS;
+ break;
+ case eModifierType_Fluidsim:
+ data.icon = ICON_MOD_FLUIDSIM;
+ break;
+ case eModifierType_Multires:
+ data.icon = ICON_MOD_MULTIRES;
+ break;
+ case eModifierType_Smoke:
+ data.icon = ICON_MOD_SMOKE;
+ break;
+ case eModifierType_Solidify:
+ data.icon = ICON_MOD_SOLIDIFY;
+ break;
+ case eModifierType_Screw:
+ data.icon = ICON_MOD_SCREW;
+ break;
+ case eModifierType_Remesh:
+ data.icon = ICON_MOD_REMESH;
+ break;
+ case eModifierType_WeightVGEdit:
+ case eModifierType_WeightVGMix:
+ case eModifierType_WeightVGProximity:
+ data.icon = ICON_MOD_VERTEX_WEIGHT;
+ break;
+ case eModifierType_DynamicPaint:
+ data.icon = ICON_MOD_DYNAMICPAINT;
+ break;
+ case eModifierType_Ocean:
+ data.icon = ICON_MOD_OCEAN;
+ break;
+ case eModifierType_Warp:
+ data.icon = ICON_MOD_WARP;
+ break;
+ case eModifierType_Skin:
+ data.icon = ICON_MOD_SKIN;
+ break;
+ case eModifierType_Triangulate:
+ data.icon = ICON_MOD_TRIANGULATE;
+ break;
+ case eModifierType_MeshCache:
+ data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */
+ break;
+ case eModifierType_MeshSequenceCache:
+ data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */
+ break;
+ case eModifierType_Wireframe:
+ data.icon = ICON_MOD_WIREFRAME;
+ break;
+ case eModifierType_LaplacianDeform:
+ data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */
+ break;
+ case eModifierType_DataTransfer:
+ data.icon = ICON_MOD_DATA_TRANSFER;
+ break;
+ case eModifierType_NormalEdit:
+ case eModifierType_WeightedNormal:
+ data.icon = ICON_MOD_NORMALEDIT;
+ break;
+ case eModifierType_Hair:
+ data.icon = ICON_STRANDS;
+ break;
+ /* Default */
+ case eModifierType_None:
+ case eModifierType_ShapeKey:
+
+ case NUM_MODIFIER_TYPES:
+ data.icon = ICON_DOT;
+ break;
+ }
+ }
+ else {
+ /* grease pencil modifiers */
+ GpencilModifierData *md = BLI_findlink(&ob->greasepencil_modifiers, tselem->nr);
+ switch ((GpencilModifierType)md->type) {
+ case eGpencilModifierType_Noise:
+ data.icon = ICON_RNDCURVE;
+ break;
+ case eGpencilModifierType_Subdiv:
+ data.icon = ICON_MOD_SUBSURF;
+ break;
+ case eGpencilModifierType_Thick:
+ data.icon = ICON_MAN_ROT;
+ break;
+ case eGpencilModifierType_Tint:
+ data.icon = ICON_COLOR;
+ break;
+ case eGpencilModifierType_Instance:
+ data.icon = ICON_MOD_ARRAY;
+ break;
+ case eGpencilModifierType_Build:
+ data.icon = ICON_MOD_BUILD;
+ break;
+ case eGpencilModifierType_Opacity:
+ data.icon = ICON_MOD_MASK;
+ break;
+ case eGpencilModifierType_Color:
+ data.icon = ICON_GROUP_VCOL;
+ break;
+ case eGpencilModifierType_Lattice:
+ data.icon = ICON_MOD_LATTICE;
+ break;
+ case eGpencilModifierType_Mirror:
+ data.icon = ICON_MOD_MIRROR;
+ break;
+ case eGpencilModifierType_Simplify:
+ data.icon = ICON_MOD_DECIM;
+ break;
+ case eGpencilModifierType_Smooth:
+ data.icon = ICON_MOD_SMOOTH;
+ break;
+ case eGpencilModifierType_Hook:
+ data.icon = ICON_HOOK;
+ break;
+ case eGpencilModifierType_Offset:
+ data.icon = ICON_MOD_DISPLACE;
+ break;
+
+ /* Default */
+ default:
+ data.icon = ICON_DOT;
+ break;
+ }
}
break;
}
case TSE_POSE_BASE:
- ICON_DRAW(ICON_ARMATURE_DATA);
+ data.icon = ICON_ARMATURE_DATA;
break;
case TSE_POSE_CHANNEL:
- ICON_DRAW(ICON_BONE_DATA);
+ data.icon = ICON_BONE_DATA;
break;
case TSE_PROXY:
- ICON_DRAW(ICON_GHOST);
+ data.icon = ICON_GHOST;
break;
case TSE_R_LAYER_BASE:
- ICON_DRAW(ICON_RENDERLAYERS);
+ data.icon = ICON_RENDERLAYERS;
break;
case TSE_SCENE_OBJECTS_BASE:
- ICON_DRAW(ICON_OUTLINER_OB_GROUP_INSTANCE);
+ data.icon = ICON_OUTLINER_OB_GROUP_INSTANCE;
break;
case TSE_R_LAYER:
- ICON_DRAW(ICON_RENDER_RESULT);
+ data.icon = ICON_RENDER_RESULT;
break;
case TSE_LINKED_LAMP:
- ICON_DRAW(ICON_LIGHT_DATA);
+ data.icon = ICON_LIGHT_DATA;
break;
case TSE_LINKED_MAT:
- ICON_DRAW(ICON_MATERIAL_DATA);
+ data.icon = ICON_MATERIAL_DATA;
break;
case TSE_POSEGRP_BASE:
- ICON_DRAW(ICON_GROUP_BONE);
+ data.icon = ICON_GROUP_BONE;
break;
case TSE_SEQUENCE:
if (te->idcode == SEQ_TYPE_MOVIE)
- ICON_DRAW(ICON_SEQUENCE);
+ data.icon = ICON_SEQUENCE;
else if (te->idcode == SEQ_TYPE_META)
- ICON_DRAW(ICON_DOT);
+ data.icon = ICON_DOT;
else if (te->idcode == SEQ_TYPE_SCENE)
- ICON_DRAW(ICON_SCENE);
+ data.icon = ICON_SCENE;
else if (te->idcode == SEQ_TYPE_SOUND_RAM)
- ICON_DRAW(ICON_SOUND);
+ data.icon = ICON_SOUND;
else if (te->idcode == SEQ_TYPE_IMAGE)
- ICON_DRAW(ICON_IMAGE_COL);
+ data.icon = ICON_IMAGE_COL;
else
- ICON_DRAW(ICON_PARTICLES);
+ data.icon = ICON_PARTICLES;
break;
case TSE_SEQ_STRIP:
- ICON_DRAW(ICON_LIBRARY_DATA_DIRECT);
+ data.icon = ICON_LIBRARY_DATA_DIRECT;
break;
case TSE_SEQUENCE_DUP:
- ICON_DRAW(ICON_OBJECT_DATA);
+ data.icon = ICON_OBJECT_DATA;
break;
case TSE_RNA_STRUCT:
if (RNA_struct_is_ID(te->rnaptr.type)) {
- arg.id = (ID *)te->rnaptr.data;
- tselem_draw_icon_uibut(&arg, RNA_struct_ui_icon(te->rnaptr.type));
+ data.drag_id = (ID *)te->rnaptr.data;
+ data.icon = RNA_struct_ui_icon(te->rnaptr.type);
}
else {
- int icon = RNA_struct_ui_icon(te->rnaptr.type);
- ICON_DRAW(icon);
+ data.icon = RNA_struct_ui_icon(te->rnaptr.type);
}
break;
case TSE_LAYER_COLLECTION:
case TSE_SCENE_COLLECTION_BASE:
case TSE_VIEW_COLLECTION_BASE:
- ICON_DRAW(ICON_GROUP);
+ {
+ Collection *collection = outliner_collection_from_tree_element(te);
+ if (collection && !(collection->flag & COLLECTION_IS_MASTER)) {
+ data.drag_id = tselem->id;
+ data.drag_parent = (data.drag_id && te->parent) ? TREESTORE(te->parent)->id : NULL;
+ }
+
+ data.icon = ICON_GROUP;
break;
+ }
/* Removed the icons from outliner. Need a better structure with Layers, Palettes and Colors */
-#if 0
case TSE_GP_LAYER:
- tselem_draw_gp_icon_uibut(&arg, tselem->id, te->directdata);
+ {
+ /* indicate whether layer is active */
+ bGPDlayer *gpl = te->directdata;
+ if (gpl->flag & GP_LAYER_ACTIVE) {
+ data.icon = ICON_GREASEPENCIL;
+ }
+ else {
+ data.icon = ICON_DOT;
+ }
break;
-#endif
+ }
default:
- ICON_DRAW(ICON_DOT);
+ data.icon = ICON_DOT;
break;
}
}
else if (tselem->id) {
+ data.drag_id = tselem->id;
+ data.drag_parent = (data.drag_id && te->parent) ? TREESTORE(te->parent)->id : NULL;
+
if (GS(tselem->id->name) == ID_OB) {
Object *ob = (Object *)tselem->id;
switch (ob->type) {
case OB_LAMP:
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_LIGHT); break;
+ data.icon = ICON_OUTLINER_OB_LIGHT; break;
case OB_MESH:
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_MESH); break;
+ data.icon = ICON_OUTLINER_OB_MESH; break;
case OB_CAMERA:
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_CAMERA); break;
+ data.icon = ICON_OUTLINER_OB_CAMERA; break;
case OB_CURVE:
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_CURVE); break;
+ data.icon = ICON_OUTLINER_OB_CURVE; break;
case OB_MBALL:
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_META); break;
+ data.icon = ICON_OUTLINER_OB_META; break;
case OB_LATTICE:
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_LATTICE); break;
+ data.icon = ICON_OUTLINER_OB_LATTICE; break;
case OB_ARMATURE:
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_ARMATURE); break;
+ data.icon = ICON_OUTLINER_OB_ARMATURE; break;
case OB_FONT:
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_FONT); break;
+ data.icon = ICON_OUTLINER_OB_FONT; break;
case OB_SURF:
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_SURFACE); break;
+ data.icon = ICON_OUTLINER_OB_SURFACE; break;
case OB_SPEAKER:
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_SPEAKER); break;
+ data.icon = ICON_OUTLINER_OB_SPEAKER; break;
case OB_LIGHTPROBE:
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_LIGHTPROBE); break;
+ data.icon = ICON_OUTLINER_OB_LIGHTPROBE; break;
case OB_EMPTY:
if (ob->dup_group) {
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_GROUP_INSTANCE);
+ data.icon = ICON_OUTLINER_OB_GROUP_INSTANCE;
}
else {
- ICON_CLICK_DRAW(ICON_OUTLINER_OB_EMPTY);
+ data.icon = ICON_OUTLINER_OB_EMPTY;
}
break;
+ case OB_GPENCIL:
+ data.icon = ICON_OUTLINER_OB_GREASEPENCIL; break;
+ break;
}
}
else {
@@ -1240,101 +1241,129 @@ static void tselem_draw_icon(
*/
switch ((short)GS(tselem->id->name)) {
case ID_SCE:
- tselem_draw_icon_uibut(&arg, ICON_SCENE_DATA); break;
+ data.icon = ICON_SCENE_DATA; break;
case ID_ME:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_MESH); break;
+ data.icon = ICON_OUTLINER_DATA_MESH; break;
case ID_CU:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_CURVE); break;
+ data.icon = ICON_OUTLINER_DATA_CURVE; break;
case ID_MB:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_META); break;
+ data.icon = ICON_OUTLINER_DATA_META; break;
case ID_LT:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_LATTICE); break;
+ data.icon = ICON_OUTLINER_DATA_LATTICE; break;
case ID_LA:
{
Lamp *la = (Lamp *)tselem->id;
switch (la->type) {
case LA_LOCAL:
- tselem_draw_icon_uibut(&arg, ICON_LIGHT_POINT); break;
+ data.icon = ICON_LIGHT_POINT; break;
case LA_SUN:
- tselem_draw_icon_uibut(&arg, ICON_LIGHT_SUN); break;
+ data.icon = ICON_LIGHT_SUN; break;
case LA_SPOT:
- tselem_draw_icon_uibut(&arg, ICON_LIGHT_SPOT); break;
+ data.icon = ICON_LIGHT_SPOT; break;
case LA_HEMI:
- tselem_draw_icon_uibut(&arg, ICON_LIGHT_HEMI); break;
+ data.icon = ICON_LIGHT_HEMI; break;
case LA_AREA:
- tselem_draw_icon_uibut(&arg, ICON_LIGHT_AREA); break;
+ data.icon = ICON_LIGHT_AREA; break;
default:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_LIGHT); break;
+ data.icon = ICON_OUTLINER_DATA_LIGHT; break;
}
break;
}
case ID_MA:
- tselem_draw_icon_uibut(&arg, ICON_MATERIAL_DATA); break;
+ data.icon = ICON_MATERIAL_DATA; break;
case ID_TE:
- tselem_draw_icon_uibut(&arg, ICON_TEXTURE_DATA); break;
+ data.icon = ICON_TEXTURE_DATA; break;
case ID_IM:
- tselem_draw_icon_uibut(&arg, ICON_IMAGE_DATA); break;
+ data.icon = ICON_IMAGE_DATA; break;
case ID_SPK:
case ID_SO:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_SPEAKER); break;
+ data.icon = ICON_OUTLINER_DATA_SPEAKER; break;
case ID_AR:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_ARMATURE); break;
+ data.icon = ICON_OUTLINER_DATA_ARMATURE; break;
case ID_CA:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_CAMERA); break;
+ data.icon = ICON_OUTLINER_DATA_CAMERA; break;
case ID_KE:
- tselem_draw_icon_uibut(&arg, ICON_SHAPEKEY_DATA); break;
+ data.icon = ICON_SHAPEKEY_DATA; break;
case ID_WO:
- tselem_draw_icon_uibut(&arg, ICON_WORLD_DATA); break;
+ data.icon = ICON_WORLD_DATA; break;
case ID_AC:
- tselem_draw_icon_uibut(&arg, ICON_ACTION); break;
+ data.icon = ICON_ACTION; break;
case ID_NLA:
- tselem_draw_icon_uibut(&arg, ICON_NLA); break;
+ data.icon = ICON_NLA; break;
case ID_TXT:
- tselem_draw_icon_uibut(&arg, ICON_SCRIPT); break;
+ data.icon = ICON_SCRIPT; break;
case ID_GR:
- tselem_draw_icon_uibut(&arg, ICON_GROUP); break;
+ data.icon = ICON_GROUP; break;
case ID_LI:
if (tselem->id->tag & LIB_TAG_MISSING) {
- tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_BROKEN);
+ data.icon = ICON_LIBRARY_DATA_BROKEN;
}
else if (((Library *)tselem->id)->parent) {
- tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_INDIRECT);
+ data.icon = ICON_LIBRARY_DATA_INDIRECT;
}
else {
- tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_DIRECT);
+ data.icon = ICON_LIBRARY_DATA_DIRECT;
}
break;
case ID_LS:
- tselem_draw_icon_uibut(&arg, ICON_LINE_DATA); break;
+ data.icon = ICON_LINE_DATA; break;
case ID_GD:
- tselem_draw_icon_uibut(&arg, ICON_GREASEPENCIL); break;
+ data.icon = ICON_OUTLINER_DATA_GREASEPENCIL; break;
case ID_LP:
{
LightProbe * lp = (LightProbe *)tselem->id;
switch (lp->type) {
case LIGHTPROBE_TYPE_CUBE:
- tselem_draw_icon_uibut(&arg, ICON_LIGHTPROBE_CUBEMAP); break;
+ data.icon = ICON_LIGHTPROBE_CUBEMAP; break;
case LIGHTPROBE_TYPE_PLANAR:
- tselem_draw_icon_uibut(&arg, ICON_LIGHTPROBE_PLANAR); break;
+ data.icon = ICON_LIGHTPROBE_PLANAR; break;
case LIGHTPROBE_TYPE_GRID:
- tselem_draw_icon_uibut(&arg, ICON_LIGHTPROBE_GRID); break;
+ data.icon = ICON_LIGHTPROBE_GRID; break;
default:
- tselem_draw_icon_uibut(&arg, ICON_LIGHTPROBE_CUBEMAP); break;
+ data.icon = ICON_LIGHTPROBE_CUBEMAP; break;
}
break;
}
case ID_BR:
- tselem_draw_icon_uibut(&arg, ICON_BRUSH_DATA); break;
+ data.icon = ICON_BRUSH_DATA; break;
case ID_SCR:
case ID_WS:
- tselem_draw_icon_uibut(&arg, ICON_SPLITSCREEN); break;
+ data.icon = ICON_SPLITSCREEN; break;
default:
break;
}
}
}
-#undef ICON_DRAW
+ return data;
+}
+
+static void tselem_draw_icon(
+ uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te,
+ float alpha, const bool is_clickable)
+{
+ TreeElementIcon data = tree_element_get_icon(tselem, te);
+
+ if (data.icon == 0) {
+ return;
+ }
+
+ if (!is_clickable || x >= xmax) {
+ /* placement of icons, copied from interface_widgets.c */
+ float aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
+ x += 2.0f * aspect;
+ y += 2.0f * aspect;
+
+ /* restrict column clip... it has been coded by simply overdrawing,
+ * doesnt work for buttons */
+ UI_icon_draw_alpha(x, y, data.icon, alpha);
+ }
+ else {
+ uiDefIconBut(
+ block, UI_BTYPE_LABEL, 0, data.icon, x, y, UI_UNIT_X, UI_UNIT_Y, NULL,
+ 0.0, 0.0, 1.0, alpha,
+ (data.drag_id && ID_IS_LINKED(data.drag_id)) ? data.drag_id->lib->name : "");
+ }
}
/**
@@ -1344,16 +1373,9 @@ static void tselem_draw_icon(
static void outliner_draw_iconrow_number(
const uiFontStyle *fstyle,
int offsx, int ys,
- const eOLDrawState active,
const int num_elements)
{
- float color[4] = {0.4f, 0.4f, 0.4f, 0.9f};
- copy_v3_fl(color, 0.2f);
- if (active != OL_DRAWSEL_NONE) {
- copy_v3_fl(color, 0.65f);
- color[3] = 1.0f;
- }
-
+ float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float ufac = 0.25f * UI_UNIT_X;
float offset_x = (float) offsx + UI_UNIT_X * 0.35f;
@@ -1417,13 +1439,13 @@ static void outliner_draw_iconrow_doit(
}
/* No inlined icon should be clickable. */
- tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f * alpha_fac, false);
+ tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.8f * alpha_fac, false);
te->xs = *offsx;
te->ys = ys;
te->xend = (short)*offsx + UI_UNIT_X;
if (num_elements > 1) {
- outliner_draw_iconrow_number(fstyle, *offsx, ys, active, num_elements);
+ outliner_draw_iconrow_number(fstyle, *offsx, ys, num_elements);
}
(*offsx) += UI_UNIT_X;
}
@@ -1451,23 +1473,19 @@ static int tree_element_id_type_to_index(TreeElement *te)
}
}
+typedef struct MergedIconRow {
+ eOLDrawState active[INDEX_ID_MAX + OB_TYPE_MAX];
+ int num_elements[INDEX_ID_MAX + OB_TYPE_MAX];
+ TreeElement *tree_element[INDEX_ID_MAX + OB_TYPE_MAX];
+} MergedIconRow;
+
static void outliner_draw_iconrow(
bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer, SpaceOops *soops,
- ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac)
+ ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac, MergedIconRow *merged)
{
eOLDrawState active;
const Object *obact = OBACT(view_layer);
- struct {
- eOLDrawState active[INDEX_ID_MAX + OB_TYPE_MAX];
- int num_elements[INDEX_ID_MAX + OB_TYPE_MAX];
- TreeElement *tree_element[INDEX_ID_MAX + OB_TYPE_MAX];
- } data = {
- .active = {0},
- .num_elements = {0},
- .tree_element = {NULL},
- };
-
for (TreeElement *te = lb->first; te; te = te->next) {
/* exit drawing early */
if ((*offsx) - UI_UNIT_X > xmax)
@@ -1498,13 +1516,13 @@ static void outliner_draw_iconrow(
}
else {
const int index = tree_element_id_type_to_index(te);
- data.num_elements[index]++;
- if ((data.tree_element[index] == NULL) ||
- (active > data.active[index]))
+ merged->num_elements[index]++;
+ if ((merged->tree_element[index] == NULL) ||
+ (active > merged->active[index]))
{
- data.tree_element[index] = te;
+ merged->tree_element[index] = te;
}
- data.active[index] = MAX2(active, data.active[index]);
+ merged->active[index] = MAX2(active, merged->active[index]);
}
}
@@ -1512,26 +1530,28 @@ static void outliner_draw_iconrow(
if (tselem->type != TSE_R_LAYER) {
outliner_draw_iconrow(
C, block, fstyle, scene, view_layer, soops,
- &te->subtree, level + 1, xmax, offsx, ys, alpha_fac);
+ &te->subtree, level + 1, xmax, offsx, ys, alpha_fac, merged);
}
}
- for (int i = 0; i < INDEX_ID_MAX; i++) {
- const int num_subtypes = (i == INDEX_ID_OB) ? OB_TYPE_MAX : 1;
- /* See tree_element_id_type_to_index for the index logic. */
- int index_base = i;
- if (i > INDEX_ID_OB) {
- index_base += OB_TYPE_MAX;
- }
- for (int j = 0; j < num_subtypes; j++) {
- const int index = index_base + j;
- if (data.num_elements[index] != 0) {
- outliner_draw_iconrow_doit(block,
- data.tree_element[index],
- fstyle,
- xmax, offsx, ys, alpha_fac,
- data.active[index],
- data.num_elements[index]);
+ if (level == 0) {
+ for (int i = 0; i < INDEX_ID_MAX; i++) {
+ const int num_subtypes = (i == INDEX_ID_OB) ? OB_TYPE_MAX : 1;
+ /* See tree_element_id_type_to_index for the index logic. */
+ int index_base = i;
+ if (i > INDEX_ID_OB) {
+ index_base += OB_TYPE_MAX;
+ }
+ for (int j = 0; j < num_subtypes; j++) {
+ const int index = index_base + j;
+ if (merged->num_elements[index] != 0) {
+ outliner_draw_iconrow_doit(block,
+ merged->tree_element[index],
+ fstyle,
+ xmax, offsx, ys, alpha_fac,
+ merged->active[index],
+ merged->num_elements[index]);
+ }
}
}
}
@@ -1558,7 +1578,7 @@ static void outliner_set_coord_tree_element(TreeElement *te, int startx, int sta
static void outliner_draw_tree_element(
bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer,
ARegion *ar, SpaceOops *soops, TreeElement *te, bool draw_grayed_out,
- int startx, int *starty, TreeElement **te_edit, TreeElement **te_floating)
+ int startx, int *starty, TreeElement **te_edit)
{
TreeStoreElem *tselem;
float ufac = UI_UNIT_X / 20.0f;
@@ -1575,9 +1595,6 @@ static void outliner_draw_tree_element(
if ((tselem->flag & TSE_TEXTBUT) && (*te_edit == NULL)) {
*te_edit = te;
}
- if ((te->drag_data != NULL) && (*te_floating == NULL)) {
- *te_floating = te;
- }
/* icons can be ui buts, we don't want it to overlap with restrict */
if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0)
@@ -1742,8 +1759,8 @@ static void outliner_draw_tree_element(
/* divider */
{
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
unsigned char col[4];
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1758,9 +1775,10 @@ static void outliner_draw_tree_element(
immUnbindProgram();
}
+ MergedIconRow merged = {{0}};
outliner_draw_iconrow(
C, block, fstyle, scene, view_layer, soops, &te->subtree, 0, xmax, &tempx,
- *starty, alpha_fac);
+ *starty, alpha_fac, &merged);
GPU_blend(false);
}
@@ -1778,11 +1796,11 @@ static void outliner_draw_tree_element(
for (TreeElement *ten = te->subtree.first; ten; ten = ten->next) {
/* check if element needs to be drawn grayed out, but also gray out
* childs of a grayed out parent (pass on draw_grayed_out to childs) */
- bool draw_childs_grayed_out = draw_grayed_out || (ten->drag_data != NULL);
+ bool draw_childs_grayed_out = draw_grayed_out || (ten->flag & TE_DRAGGING);
outliner_draw_tree_element(
C, block, fstyle, scene, view_layer,
ar, soops, ten, draw_childs_grayed_out,
- startx + UI_UNIT_X, starty, te_edit, te_floating);
+ startx + UI_UNIT_X, starty, te_edit);
}
}
else {
@@ -1794,54 +1812,6 @@ static void outliner_draw_tree_element(
}
}
-static void outliner_draw_tree_element_floating(
- const ARegion *ar, const TreeElement *te_floating)
-{
- const TreeElement *te_insert = te_floating->drag_data->insert_handle;
- const int line_width = 2;
-
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- int coord_y = te_insert->ys;
- int coord_x = te_insert->xs;
- float col[4];
-
- if (te_insert == te_floating) {
- /* don't draw anything */
- return;
- }
-
- UI_GetThemeColorShade4fv(TH_BACK, -40, col);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(true);
-
- if (ELEM(te_floating->drag_data->insert_type, TE_INSERT_BEFORE, TE_INSERT_AFTER)) {
- if (te_floating->drag_data->insert_type == TE_INSERT_BEFORE) {
- coord_y += UI_UNIT_Y;
- }
- immUniformColor4fv(col);
- GPU_line_width(line_width);
-
- immBegin(GWN_PRIM_LINE_STRIP, 2);
- immVertex2f(pos, coord_x, coord_y);
- immVertex2f(pos, ar->v2d.cur.xmax, coord_y);
- immEnd();
- }
- else {
- BLI_assert(te_floating->drag_data->insert_type == TE_INSERT_INTO);
- immUniformColor3fvAlpha(col, col[3] * 0.5f);
-
- immBegin(GWN_PRIM_TRI_STRIP, 4);
- immVertex2f(pos, coord_x, coord_y + UI_UNIT_Y);
- immVertex2f(pos, coord_x, coord_y);
- immVertex2f(pos, ar->v2d.cur.xmax, coord_y + UI_UNIT_Y);
- immVertex2f(pos, ar->v2d.cur.xmax, coord_y);
- immEnd();
- }
-
- GPU_blend(false);
- immUnbindProgram();
-}
-
static void outliner_draw_hierarchy_lines_recursive(
unsigned pos, SpaceOops *soops, ListBase *lb, int startx,
const unsigned char col[4], bool draw_grayed_out,
@@ -1859,7 +1829,7 @@ static void outliner_draw_hierarchy_lines_recursive(
/* For vertical lines between objects. */
y1 = y2 = *starty;
for (te = lb->first; te; te = te->next) {
- bool draw_childs_grayed_out = draw_grayed_out || (te->drag_data != NULL);
+ bool draw_childs_grayed_out = draw_grayed_out || (te->flag & TE_DRAGGING);
TreeStoreElem *tselem = TREESTORE(te);
if (draw_childs_grayed_out) {
@@ -1904,8 +1874,8 @@ static void outliner_draw_hierarchy_lines_recursive(
static void outliner_draw_hierarchy_lines(SpaceOops *soops, ListBase *lb, int startx, int *starty)
{
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
unsigned char col[4];
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1927,8 +1897,8 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *
/* selection status */
if (TSELEM_OPEN(tselem, soops)) {
if (tselem->type == TSE_RNA_STRUCT) {
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immThemeColorShadeAlpha(TH_BACK, -15, -200);
immRecti(pos, 0, *starty + 1, (int)ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
@@ -1940,12 +1910,12 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *
if (TSELEM_OPEN(tselem, soops)) {
outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
if (tselem->type == TSE_RNA_STRUCT) {
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immThemeColorShadeAlpha(TH_BACK, -15, -200);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, 0, (float)*starty + UI_UNIT_Y);
immVertex2f(pos, ar->v2d.cur.xmax, (float)*starty + UI_UNIT_Y);
immEnd();
@@ -1976,18 +1946,42 @@ static void outliner_draw_highlights_recursive(
immRecti(pos, 0, start_y + 1, (int)ar->v2d.cur.xmax, start_y + UI_UNIT_Y - 1);
}
- /* search match highlights
- * we don't expand items when searching in the datablocks but we
- * still want to highlight any filter matches. */
- if (is_searching && (tselem->flag & TSE_SEARCHMATCH)) {
- immUniformColor4fv(col_searchmatch);
- immRecti(pos, start_x, start_y + 1, ar->v2d.cur.xmax, start_y + UI_UNIT_Y - 1);
- }
+ /* highlights */
+ if (tselem->flag & (TSE_DRAG_ANY | TSE_HIGHLIGHTED | TSE_SEARCHMATCH)) {
+ const int end_x = (int)ar->v2d.cur.xmax;
- /* mouse hover highlights */
- if ((tselem->flag & TSE_HIGHLIGHTED) || (te->drag_data != NULL)) {
- immUniformColor4fv(col_highlight);
- immRecti(pos, 0, start_y + 1, (int)ar->v2d.cur.xmax, start_y + UI_UNIT_Y - 1);
+ if (tselem->flag & TSE_DRAG_ANY) {
+ /* drag and drop highlight */
+ float col[4];
+ UI_GetThemeColorShade4fv(TH_BACK, -40, col);
+
+ if (tselem->flag & TSE_DRAG_BEFORE) {
+ immUniformColor4fv(col);
+ immRecti(pos, start_x, start_y + UI_UNIT_Y - 1, end_x, start_y + UI_UNIT_Y + 1);
+ }
+ else if (tselem->flag & TSE_DRAG_AFTER) {
+ immUniformColor4fv(col);
+ immRecti(pos, start_x, start_y - 1, end_x, start_y + 1);
+ }
+ else {
+ immUniformColor3fvAlpha(col, col[3] * 0.5f);
+ immRecti(pos, start_x, start_y + 1, end_x, start_y + UI_UNIT_Y - 1);
+ }
+ }
+ else {
+ if (is_searching && (tselem->flag & TSE_SEARCHMATCH)) {
+ /* search match highlights
+ * we don't expand items when searching in the datablocks but we
+ * still want to highlight any filter matches. */
+ immUniformColor4fv(col_searchmatch);
+ immRecti(pos, start_x, start_y + 1, end_x, start_y + UI_UNIT_Y - 1);
+ }
+ else if (tselem->flag & TSE_HIGHLIGHTED) {
+ /* mouse hover highlight */
+ immUniformColor4fv(col_highlight);
+ immRecti(pos, 0, start_y + 1, end_x, start_y + UI_UNIT_Y - 1);
+ }
+ }
}
*io_start_y -= UI_UNIT_Y;
@@ -2010,8 +2004,8 @@ static void outliner_draw_highlights(ARegion *ar, SpaceOops *soops, int startx,
col_searchmatch[3] = 0.5f;
GPU_blend(true);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
outliner_draw_highlights_recursive(
pos, ar, soops, &soops->tree, col_selection, col_highlight, col_searchmatch,
@@ -2026,7 +2020,6 @@ static void outliner_draw_tree(
TreeElement **te_edit)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- TreeElement *te_floating = NULL;
int starty, startx;
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); // only once
@@ -2064,11 +2057,8 @@ static void outliner_draw_tree(
for (TreeElement *te = soops->tree.first; te; te = te->next) {
outliner_draw_tree_element(
C, block, fstyle, scene, view_layer,
- ar, soops, te, te->drag_data != NULL,
- startx, &starty, te_edit, &te_floating);
- }
- if (te_floating && te_floating->drag_data->insert_handle) {
- outliner_draw_tree_element_floating(ar, te_floating);
+ ar, soops, te, (te->flag & TE_DRAGGING) != 0,
+ startx, &starty, te_edit);
}
if (has_restrict_icons) {
@@ -2085,8 +2075,8 @@ static void outliner_back(ARegion *ar)
ystart = (int)ar->v2d.tot.ymax;
ystart = UI_UNIT_Y * (ystart / (UI_UNIT_Y)) - OL_Y_OFFSET;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShade(TH_BACK, 6);
@@ -2096,7 +2086,7 @@ static void outliner_back(ARegion *ar)
int tot = (int)floor(ystart - ar->v2d.cur.ymin + 2 * UI_UNIT_Y) / (2 * UI_UNIT_Y);
if (tot > 0) {
- immBegin(GWN_PRIM_TRIS, 6 * tot);
+ immBegin(GPU_PRIM_TRIS, 6 * tot);
while (tot--) {
y1 -= 2 * UI_UNIT_Y;
y2 = y1 + UI_UNIT_Y;
@@ -2117,10 +2107,10 @@ static void outliner_draw_restrictcols(ARegion *ar)
{
GPU_line_width(1.0f);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShadeAlpha(TH_BACK, -15, -200);
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), (int)ar->v2d.cur.ymax);
immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), (int)ar->v2d.cur.ymin);
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index d9bcf05fa29..e895ff53bc5 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -90,73 +90,17 @@
#include "outliner_intern.h"
/* ************************************************************** */
-/* Unused Utilities */
-// XXX: where to place these?
-
-/* This is not used anywhere at the moment */
-#if 0
-static void outliner_open_reveal(SpaceOops *soops, ListBase *lb, TreeElement *teFind, int *found)
-{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- for (te = lb->first; te; te = te->next) {
- /* check if this tree-element was the one we're seeking */
- if (te == teFind) {
- *found = 1;
- return;
- }
-
- /* try to see if sub-tree contains it then */
- outliner_open_reveal(soops, &te->subtree, teFind, found);
- if (*found) {
- tselem = TREESTORE(te);
- if (tselem->flag & TSE_CLOSED)
- tselem->flag &= ~TSE_CLOSED;
- return;
- }
- }
-}
-#endif
-
-static TreeElement *outliner_dropzone_element(TreeElement *te, const float fmval[2], const bool children)
-{
- if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) {
- /* name and first icon */
- if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend))
- return te;
- }
- /* Not it. Let's look at its children. */
- if (children && (TREESTORE(te)->flag & TSE_CLOSED) == 0 && (te->subtree.first)) {
- for (te = te->subtree.first; te; te = te->next) {
- TreeElement *te_valid = outliner_dropzone_element(te, fmval, children);
- if (te_valid)
- return te_valid;
- }
- }
- return NULL;
-}
-
-/* Used for drag and drop parenting */
-TreeElement *outliner_dropzone_find(const SpaceOops *soops, const float fmval[2], const bool children)
-{
- TreeElement *te;
-
- for (te = soops->tree.first; te; te = te->next) {
- TreeElement *te_valid = outliner_dropzone_element(te, fmval, children);
- if (te_valid)
- return te_valid;
- }
- return NULL;
-}
-
-
-/* ************************************************************** */
/* Highlight --------------------------------------------------- */
static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
+ /* Drag and drop does own highlighting. */
+ wmWindowManager *wm = CTX_wm_manager(C);
+ if (wm->drags.first) {
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
@@ -165,7 +109,7 @@ static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const
bool changed = false;
if (!hovered_te || !(hovered_te->store_elem->flag & TSE_HIGHLIGHTED)) {
- changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED, false);
+ changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false);
if (hovered_te) {
hovered_te->store_elem->flag |= TSE_HIGHLIGHTED;
changed = true;
@@ -1951,474 +1895,3 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
-/* ************************************************************** */
-/* DRAG AND DROP OPERATORS */
-
-/* ******************** Parent Drop Operator *********************** */
-
-static int parent_drop_exec(bContext *C, wmOperator *op)
-{
- Object *par = NULL, *ob = NULL;
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- int partype = -1;
- char parname[MAX_ID_NAME], childname[MAX_ID_NAME];
-
- partype = RNA_enum_get(op->ptr, "type");
- RNA_string_get(op->ptr, "parent", parname);
- par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname);
- RNA_string_get(op->ptr, "child", childname);
- ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname);
-
- if (ID_IS_LINKED(ob)) {
- BKE_report(op->reports, RPT_INFO, "Can't edit library linked object");
- return OPERATOR_CANCELLED;
- }
-
- ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL);
-
- DEG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
- WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- Object *par = NULL;
- Object *ob = NULL;
- SpaceOops *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = NULL;
- TreeElement *te = NULL;
- char childname[MAX_ID_NAME];
- char parname[MAX_ID_NAME];
- int partype = 0;
- float fmval[2];
-
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
- /* Find object hovered over */
- te = outliner_dropzone_find(soops, fmval, true);
-
- if (te) {
- RNA_string_set(op->ptr, "parent", te->name);
- /* Identify parent and child */
- RNA_string_get(op->ptr, "child", childname);
- ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname);
- RNA_string_get(op->ptr, "parent", parname);
- par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname);
-
- if (ELEM(NULL, ob, par)) {
- if (par == NULL) printf("par==NULL\n");
- return OPERATOR_CANCELLED;
- }
- if (ob == par) {
- return OPERATOR_CANCELLED;
- }
- if (ID_IS_LINKED(ob)) {
- BKE_report(op->reports, RPT_INFO, "Can't edit library linked object");
- return OPERATOR_CANCELLED;
- }
-
- scene = (Scene *)outliner_search_back(soops, te, ID_SCE);
-
- if (scene == NULL) {
- /* currently outlier organized in a way, that if there's no parent scene
- * element for object it means that all displayed objects belong to
- * active scene and parenting them is allowed (sergey)
- */
-
- scene = CTX_data_scene(C);
- }
-
- if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) {
- if (ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL)) {
- DEG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
- WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
- }
- }
- else {
- /* Menu creation */
- wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false);
- uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE);
- uiLayout *layout = UI_popup_menu_layout(pup);
- PointerRNA ptr;
-
- /* Cannot use uiItemEnumO()... have multiple properties to set. */
- uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_OBJECT);
-
- /* par becomes parent, make the associated menus */
- if (par->type == OB_ARMATURE) {
- uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_ARMATURE);
-
- uiItemFullO_ptr(layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME);
-
- uiItemFullO_ptr(layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE);
-
- uiItemFullO_ptr(layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO);
-
- uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_BONE);
- }
- else if (par->type == OB_CURVE) {
- uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_CURVE);
-
- uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_FOLLOW);
-
- uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_PATH_CONST);
- }
- else if (par->type == OB_LATTICE) {
- uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_LATTICE);
- }
-
- UI_popup_menu_end(C, pup);
-
- return OPERATOR_INTERFACE;
- }
- }
- else {
- return OPERATOR_CANCELLED;
- }
-
- return OPERATOR_FINISHED;
-}
-
-void OUTLINER_OT_parent_drop(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Drop to Set Parent";
- ot->description = "Drag to parent in Outliner";
- ot->idname = "OUTLINER_OT_parent_drop";
-
- /* api callbacks */
- ot->invoke = parent_drop_invoke;
- ot->exec = parent_drop_exec;
-
- ot->poll = ED_operator_outliner_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
-
- /* properties */
- RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object");
- RNA_def_string(ot->srna, "parent", "Object", MAX_ID_NAME, "Parent", "Parent Object");
- RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
-}
-
-static bool outliner_parenting_poll(bContext *C)
-{
- SpaceOops *soops = CTX_wm_space_outliner(C);
-
- if (soops) {
- if (soops->outlinevis == SO_SCENES) {
- return true;
- }
- else if ((soops->outlinevis == SO_VIEW_LAYER) &&
- (soops->filter & SO_FILTER_NO_COLLECTION))
- {
- return true;
- }
- }
-
- return false;
-}
-
-static int parent_clear_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
-{
- Main *bmain = CTX_data_main(C);
- Object *ob = NULL;
- SpaceOops *soops = CTX_wm_space_outliner(C);
- char obname[MAX_ID_NAME];
-
- RNA_string_get(op->ptr, "dragged_obj", obname);
- ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, obname);
-
- /* search forwards to find the object */
- outliner_find_id(soops, &soops->tree, (ID *)ob);
-
- ED_object_parent_clear(ob, RNA_enum_get(op->ptr, "type"));
-
- DEG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
- WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
- return OPERATOR_FINISHED;
-}
-
-void OUTLINER_OT_parent_clear(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Drop to Clear Parent";
- ot->description = "Drag to clear parent in Outliner";
- ot->idname = "OUTLINER_OT_parent_clear";
-
- /* api callbacks */
- ot->invoke = parent_clear_invoke;
-
- ot->poll = outliner_parenting_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
-
- /* properties */
- RNA_def_string(ot->srna, "dragged_obj", "Object", MAX_ID_NAME, "Child", "Child Object");
- RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", "");
-}
-
-static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- Scene *scene = NULL;
- Object *ob = NULL;
- SpaceOops *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- Main *bmain = CTX_data_main(C);
- TreeElement *te = NULL;
- char obname[MAX_ID_NAME];
- float fmval[2];
-
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
- /* Find object hovered over */
- te = outliner_dropzone_find(soops, fmval, false);
-
- if (te) {
- RNA_string_set(op->ptr, "scene", te->name);
- scene = (Scene *)BKE_libblock_find_name(bmain, ID_SCE, te->name);
-
- RNA_string_get(op->ptr, "object", obname);
- ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, obname);
-
- if (ELEM(NULL, ob, scene) || ID_IS_LINKED(scene)) {
- return OPERATOR_CANCELLED;
- }
-
- if (BKE_scene_has_object(scene, ob)) {
- return OPERATOR_CANCELLED;
- }
-
- Collection *collection;
- if (scene != CTX_data_scene(C)) {
- /* when linking to an inactive scene link to the master collection */
- collection = BKE_collection_master(scene);
- }
- else {
- collection = CTX_data_collection(C);
- }
-
- BKE_collection_object_add(bmain, collection, ob);
-
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
- Base *base = BKE_view_layer_base_find(view_layer, ob);
- if (base) {
- ED_object_base_select(base, BA_SELECT);
- }
- }
-
- DEG_relations_tag_update(bmain);
-
- DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE);
- WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
-
- return OPERATOR_FINISHED;
- }
-
- return OPERATOR_CANCELLED;
-}
-
-void OUTLINER_OT_scene_drop(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Drop Object to Scene";
- ot->description = "Drag object to scene in Outliner";
- ot->idname = "OUTLINER_OT_scene_drop";
-
- /* api callbacks */
- ot->invoke = scene_drop_invoke;
-
- ot->poll = ED_operator_outliner_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
-
- /* properties */
- RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object");
- RNA_def_string(ot->srna, "scene", "Scene", MAX_ID_NAME, "Scene", "Target Scene");
-}
-
-static int material_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- Material *ma = NULL;
- Object *ob = NULL;
- Main *bmain = CTX_data_main(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- TreeElement *te = NULL;
- char mat_name[MAX_ID_NAME - 2];
- float fmval[2];
-
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
- /* Find object hovered over */
- te = outliner_dropzone_find(soops, fmval, true);
-
- if (te) {
- RNA_string_set(op->ptr, "object", te->name);
- ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, te->name);
-
- RNA_string_get(op->ptr, "material", mat_name);
- ma = (Material *)BKE_libblock_find_name(bmain, ID_MA, mat_name);
-
- if (ELEM(NULL, ob, ma)) {
- return OPERATOR_CANCELLED;
- }
-
- assign_material(bmain, ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
-
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
-
- return OPERATOR_FINISHED;
- }
-
- return OPERATOR_CANCELLED;
-}
-
-void OUTLINER_OT_material_drop(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Drop Material on Object";
- ot->description = "Drag material to object in Outliner";
- ot->idname = "OUTLINER_OT_material_drop";
-
- /* api callbacks */
- ot->invoke = material_drop_invoke;
-
- ot->poll = ED_operator_outliner_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
-
- /* properties */
- RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object");
- RNA_def_string(ot->srna, "material", "Material", MAX_ID_NAME, "Material", "Target Material");
-}
-
-/* ******************** Collection Drop Operator *********************** */
-
-static int collection_drop_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
-{
- /* TODO: implement */
-#if 0
- Object *par = NULL, *ob = NULL;
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- int partype = -1;
- char parname[MAX_ID_NAME], childname[MAX_ID_NAME];
-
- RNA_string_get(op->ptr, "parent", parname);
- par = (Object *)BKE_libblock_find_name(ID_OB, parname);
- RNA_string_get(op->ptr, "child", childname);
- ob = (Object *)BKE_libblock_find_name(ID_OB, childname);
-
- if (ID_IS_LINKED(ob)) {
- BKE_report(op->reports, RPT_INFO, "Can't edit library linked object");
- return OPERATOR_CANCELLED;
- }
-
- ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL);
-
- DEG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
- WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
-#endif
-
- return OPERATOR_FINISHED;
-}
-
-static int collection_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- SpaceOops *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- Main *bmain = CTX_data_main(C);
- char childname[MAX_ID_NAME];
- float fmval[2];
-
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
- /* Find object hovered over */
- TreeElement *te = outliner_dropzone_find(soops, fmval, true);
-
- if (!te || !outliner_is_collection_tree_element(te)) {
- return OPERATOR_CANCELLED;
- }
-
- Collection *collection = outliner_collection_from_tree_element(te);
-
- // TODO: don't use scene, makes no sense anymore
- // TODO: move rather than link, change hover text
- Scene *scene = BKE_scene_find_from_collection(bmain, collection);
- BLI_assert(scene);
- RNA_string_get(op->ptr, "child", childname);
- Object *ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname);
- BKE_collection_object_add(bmain, collection, ob);
-
- DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
-
- return OPERATOR_FINISHED;
-}
-
-void OUTLINER_OT_collection_drop(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Link to Collection"; // TODO: rename to move?
- ot->description = "Drag to move to collection in Outliner";
- ot->idname = "OUTLINER_OT_collection_drop";
-
- /* api callbacks */
- ot->invoke = collection_drop_invoke;
- ot->exec = collection_drop_exec;
-
- ot->poll = ED_operator_outliner_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
-
- /* properties */
- RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object");
- RNA_def_string(ot->srna, "parent", "Collection", MAX_ID_NAME, "Parent", "Parent Collection");
-}
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 093ad9361c2..f8dc41b8d37 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -67,23 +67,6 @@ typedef enum TreeTraversalAction {
TRAVERSE_SKIP_CHILDS,
} TreeTraversalAction;
-/**
- * Callback type for reinserting elements at a different position, used to allow user customizable element order.
- */
-typedef void (*TreeElementReinsertFunc)(struct Main *bmain,
- struct Scene *scene,
- struct SpaceOops *soops,
- struct TreeElement *insert_element,
- struct TreeElement *insert_handle,
- TreeElementInsertType action,
- const struct wmEvent *event);
-/**
- * Executed on (almost) each mouse move while dragging. It's supposed to give info
- * if reinserting insert_element before/after/into insert_handle would be allowed.
- * It's allowed to change the reinsert info here for non const pointers.
- */
-typedef bool (*TreeElementReinsertPollFunc)(const struct TreeElement *insert_element,
- struct TreeElement **io_insert_handle, TreeElementInsertType *io_action);
typedef TreeTraversalAction (*TreeTraversalFunc)(struct TreeElement *te, void *customdata);
@@ -99,19 +82,13 @@ typedef struct TreeElement {
const char *name;
void *directdata; // Armature Bones, Base, Sequence, Strip...
PointerRNA rnaptr; // RNA Pointer
-
- /* callbacks - TODO should be moved into a type (like TreeElementType) */
- TreeElementReinsertFunc reinsert;
- TreeElementReinsertPollFunc reinsert_poll;
-
- struct {
- TreeElementInsertType insert_type;
- /* the element before/after/into which we may insert the dragged one (NULL to insert at top) */
- struct TreeElement *insert_handle;
- void *tooltip_draw_handle;
- } *drag_data;
} TreeElement;
+typedef struct TreeElementIcon {
+ struct ID *drag_id, *drag_parent;
+ int icon;
+} TreeElementIcon;
+
#define TREESTORE_ID_TYPE(_id) \
(ELEM(GS((_id)->name), ID_SCE, ID_LI, ID_OB, ID_ME, ID_CU, ID_MB, ID_NT, ID_MA, ID_TE, ID_IM, ID_LT, ID_LA, ID_CA) || \
ELEM(GS((_id)->name), ID_KE, ID_WO, ID_SPK, ID_GR, ID_AR, ID_AC, ID_BR, ID_PA, ID_GD, ID_LS, ID_LP) || \
@@ -126,6 +103,7 @@ enum {
TE_LAZY_CLOSED = (1 << 2),
TE_FREE_NAME = (1 << 3),
TE_DISABLED = (1 << 4),
+ TE_DRAGGING = (1 << 5),
};
/* button events */
@@ -209,6 +187,8 @@ TreeTraversalAction outliner_find_selected_objects(struct TreeElement *te, void
void draw_outliner(const struct bContext *C);
void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag);
+TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te);
+
/* outliner_select.c -------------------------------------------- */
eOLDrawState tree_element_type_active(
struct bContext *C, struct Scene *scene, struct ViewLayer *view_layer, struct SpaceOops *soops,
@@ -284,10 +264,18 @@ void item_object_mode_exit_cb(
struct bContext *C, struct ReportList *reports, struct Scene *scene,
TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
-TreeElement *outliner_dropzone_find(const struct SpaceOops *soops, const float fmval[2], const bool children);
-
void outliner_set_coordinates(struct ARegion *ar, struct SpaceOops *soops);
+/* outliner_dragdrop.c */
+void outliner_dropboxes(void);
+
+void OUTLINER_OT_item_drag_drop(struct wmOperatorType *ot);
+void OUTLINER_OT_parent_drop(struct wmOperatorType *ot);
+void OUTLINER_OT_parent_clear(struct wmOperatorType *ot);
+void OUTLINER_OT_scene_drop(struct wmOperatorType *ot);
+void OUTLINER_OT_material_drop(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_drop(struct wmOperatorType *ot);
+
/* ...................................................... */
void OUTLINER_OT_highlight_update(struct wmOperatorType *ot);
@@ -319,12 +307,6 @@ void OUTLINER_OT_drivers_delete_selected(struct wmOperatorType *ot);
void OUTLINER_OT_orphans_purge(struct wmOperatorType *ot);
-void OUTLINER_OT_parent_drop(struct wmOperatorType *ot);
-void OUTLINER_OT_parent_clear(struct wmOperatorType *ot);
-void OUTLINER_OT_scene_drop(struct wmOperatorType *ot);
-void OUTLINER_OT_material_drop(struct wmOperatorType *ot);
-void OUTLINER_OT_collection_drop(struct wmOperatorType *ot);
-
/* outliner_tools.c ---------------------------------------------- */
void OUTLINER_OT_operation(struct wmOperatorType *ot);
@@ -358,7 +340,11 @@ void OUTLINER_OT_collection_objects_deselect(struct wmOperatorType *ot);
void OUTLINER_OT_collection_link(struct wmOperatorType *ot);
void OUTLINER_OT_collection_instance(struct wmOperatorType *ot);
void OUTLINER_OT_collection_exclude_set(struct wmOperatorType *ot);
-void OUTLINER_OT_collection_include_set(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_exclude_clear(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_holdout_set(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_holdout_clear(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_indirect_only_set(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_indirect_only_clear(struct wmOperatorType *ot);
/* outliner_utils.c ---------------------------------------------- */
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 0dd492839c9..34d79ea5a61 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -55,353 +55,6 @@
#include "outliner_intern.h"
-typedef struct OutlinerDragDropTooltip {
- TreeElement *te;
- void *handle;
-} OutlinerDragDropTooltip;
-
-enum {
- OUTLINER_ITEM_DRAG_CANCEL,
- OUTLINER_ITEM_DRAG_CONFIRM,
-};
-
-static bool outliner_item_drag_drop_poll(bContext *C)
-{
- SpaceOops *soops = CTX_wm_space_outliner(C);
- return ED_operator_outliner_active(C) &&
- /* Only collection display modes supported for now. Others need more design work */
- ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_LIBRARIES);
-}
-
-static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event)
-{
- /* note: using EVT_TWEAK_ events to trigger dragging is fine,
- * it sends coordinates from where dragging was started */
- const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
- return outliner_find_item_at_y(soops, &soops->tree, my);
-}
-
-static void outliner_item_drag_end(wmWindow *win, OutlinerDragDropTooltip *data)
-{
- MEM_SAFE_FREE(data->te->drag_data);
-
- if (data->handle) {
- WM_draw_cb_exit(win, data->handle);
- }
-
- MEM_SAFE_FREE(data);
-}
-
-static void outliner_item_drag_get_insert_data(
- const SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged,
- TreeElement **r_te_insert_handle, TreeElementInsertType *r_insert_type)
-{
- TreeElement *te_hovered;
- float view_mval[2];
-
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
- te_hovered = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]);
-
- if (te_hovered) {
- /* mouse hovers an element (ignoring x-axis), now find out how to insert the dragged item exactly */
-
- if (te_hovered == te_dragged) {
- *r_te_insert_handle = te_dragged;
- }
- else if (te_hovered != te_dragged) {
- const float margin = UI_UNIT_Y * (1.0f / 4);
-
- *r_te_insert_handle = te_hovered;
- if (view_mval[1] < (te_hovered->ys + margin)) {
- if (TSELEM_OPEN(TREESTORE(te_hovered), soops)) {
- /* inserting after a open item means we insert into it, but as first child */
- if (BLI_listbase_is_empty(&te_hovered->subtree)) {
- *r_insert_type = TE_INSERT_INTO;
- }
- else {
- *r_insert_type = TE_INSERT_BEFORE;
- *r_te_insert_handle = te_hovered->subtree.first;
- }
- }
- else {
- *r_insert_type = TE_INSERT_AFTER;
- }
- }
- else if (view_mval[1] > (te_hovered->ys + (3 * margin))) {
- *r_insert_type = TE_INSERT_BEFORE;
- }
- else {
- *r_insert_type = TE_INSERT_INTO;
- }
- }
- }
- else {
- /* mouse doesn't hover any item (ignoring x-axis), so it's either above list bounds or below. */
-
- TreeElement *first = soops->tree.first;
- TreeElement *last = soops->tree.last;
-
- if (view_mval[1] < last->ys) {
- *r_te_insert_handle = last;
- *r_insert_type = TE_INSERT_AFTER;
- }
- else if (view_mval[1] > (first->ys + UI_UNIT_Y)) {
- *r_te_insert_handle = first;
- *r_insert_type = TE_INSERT_BEFORE;
- }
- else {
- BLI_assert(0);
- }
- }
-}
-
-static void outliner_item_drag_handle(
- SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged)
-{
- TreeElement *te_insert_handle;
- TreeElementInsertType insert_type;
-
- outliner_item_drag_get_insert_data(soops, ar, event, te_dragged, &te_insert_handle, &insert_type);
-
- if (!te_dragged->reinsert_poll &&
- /* there is no reinsert_poll, so we do some generic checks (same types and reinsert callback is available) */
- (TREESTORE(te_dragged)->type == TREESTORE(te_insert_handle)->type) &&
- te_dragged->reinsert)
- {
- /* pass */
- }
- else if (te_dragged == te_insert_handle) {
- /* nothing will happen anyway, no need to do poll check */
- }
- else if (!te_dragged->reinsert_poll ||
- !te_dragged->reinsert_poll(te_dragged, &te_insert_handle, &insert_type))
- {
- te_insert_handle = NULL;
- }
- te_dragged->drag_data->insert_type = insert_type;
- te_dragged->drag_data->insert_handle = te_insert_handle;
-}
-
-/**
- * Returns true if it is a collection and empty.
- */
-static bool is_empty_collection(TreeElement *te)
-{
- Collection *collection = outliner_collection_from_tree_element(te);
-
- if (!collection) {
- return false;
- }
-
- return BLI_listbase_is_empty(&collection->gobject) &&
- BLI_listbase_is_empty(&collection->children);
-}
-
-static bool outliner_item_drag_drop_apply(
- Main *bmain,
- Scene *scene,
- SpaceOops *soops,
- OutlinerDragDropTooltip *data,
- const wmEvent *event)
-{
- TreeElement *dragged_te = data->te;
- TreeElement *insert_handle = dragged_te->drag_data->insert_handle;
- TreeElementInsertType insert_type = dragged_te->drag_data->insert_type;
-
- if ((insert_handle == dragged_te) || !insert_handle) {
- /* No need to do anything */
- }
- else if (dragged_te->reinsert) {
- BLI_assert(!dragged_te->reinsert_poll || dragged_te->reinsert_poll(dragged_te, &insert_handle,
- &insert_type));
- /* call of assert above should not have changed insert_handle and insert_type at this point */
- BLI_assert(dragged_te->drag_data->insert_handle == insert_handle &&
- dragged_te->drag_data->insert_type == insert_type);
-
- /* If the collection was just created and you moved objects/collections inside it,
- * it is strange to have it closed and we not see the newly dragged elements. */
- const bool should_open_collection = (insert_type == TE_INSERT_INTO) && is_empty_collection(insert_handle);
-
- dragged_te->reinsert(bmain, scene, soops, dragged_te, insert_handle, insert_type, event);
-
- if (should_open_collection && !is_empty_collection(insert_handle)) {
- TREESTORE(insert_handle)->flag &= ~TSE_CLOSED;
- }
- return true;
- }
-
- return false;
-}
-
-static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEvent *event)
-{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ARegion *ar = CTX_wm_region(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- OutlinerDragDropTooltip *data = op->customdata;
- TreeElement *te_dragged = data->te;
- int retval = OPERATOR_RUNNING_MODAL;
- bool redraw = false;
- bool skip_rebuild = true;
-
- switch (event->type) {
- case EVT_MODAL_MAP:
- if (event->val == OUTLINER_ITEM_DRAG_CONFIRM) {
- if (outliner_item_drag_drop_apply(bmain, scene, soops, data, event)) {
- skip_rebuild = false;
- }
- retval = OPERATOR_FINISHED;
- }
- else if (event->val == OUTLINER_ITEM_DRAG_CANCEL) {
- retval = OPERATOR_CANCELLED;
- }
- else {
- BLI_assert(0);
- }
- WM_event_add_mousemove(C); /* update highlight */
- outliner_item_drag_end(CTX_wm_window(C), data);
- redraw = true;
- break;
- case MOUSEMOVE:
- outliner_item_drag_handle(soops, ar, event, te_dragged);
- redraw = true;
- break;
- }
-
- if (redraw) {
- if (skip_rebuild) {
- ED_region_tag_redraw_no_rebuild(ar);
- }
- else {
- ED_region_tag_redraw(ar);
- }
- }
-
- return retval;
-}
-
-static const char *outliner_drag_drop_tooltip_get(
- const TreeElement *te_float)
-{
- const char *name = NULL;
-
- const TreeElement *te_insert = te_float->drag_data->insert_handle;
- if (te_float && outliner_is_collection_tree_element(te_float)) {
- if (te_insert == NULL) {
- name = TIP_("Move collection");
- }
- else {
- switch (te_float->drag_data->insert_type) {
- case TE_INSERT_BEFORE:
- if (te_insert->prev && outliner_is_collection_tree_element(te_insert->prev)) {
- name = TIP_("Move between collections");
- }
- else {
- name = TIP_("Move before collection");
- }
- break;
- case TE_INSERT_AFTER:
- if (te_insert->next && outliner_is_collection_tree_element(te_insert->next)) {
- name = TIP_("Move between collections");
- }
- else {
- name = TIP_("Move after collection");
- }
- break;
- case TE_INSERT_INTO:
- name = TIP_("Move inside collection");
- break;
- }
- }
- }
- else if ((TREESTORE(te_float)->type == 0) && (te_float->idcode == ID_OB)) {
- name = TIP_("Move to collection (Ctrl to link)");
- }
-
- return name;
-}
-
-static void outliner_drag_drop_tooltip_cb(const wmWindow *win, void *vdata)
-{
- OutlinerDragDropTooltip *data = vdata;
- const char *tooltip;
-
- int cursorx, cursory;
- int x, y;
-
- tooltip = outliner_drag_drop_tooltip_get(data->te);
- if (tooltip == NULL) {
- return;
- }
-
- cursorx = win->eventstate->x;
- cursory = win->eventstate->y;
-
- x = cursorx + U.widget_unit;
- y = cursory - U.widget_unit;
-
- /* Drawing. */
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
-
- const float col_fg[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f};
-
- GPU_blend(true);
- UI_fontstyle_draw_simple_backdrop(fstyle, x, y, tooltip, col_fg, col_bg);
- GPU_blend(false);
-}
-
-static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- ARegion *ar = CTX_wm_region(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- TreeElement *te_dragged = outliner_item_drag_element_find(soops, ar, event);
-
- if (!te_dragged) {
- return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
- }
-
- OutlinerDragDropTooltip *data = MEM_mallocN(sizeof(OutlinerDragDropTooltip), __func__);
- data->te = te_dragged;
-
- op->customdata = data;
- te_dragged->drag_data = MEM_callocN(sizeof(*te_dragged->drag_data), __func__);
- /* by default we don't change the item position */
- te_dragged->drag_data->insert_handle = te_dragged;
- /* unset highlighted tree element, dragged one will be highlighted instead */
- outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED, false);
-
- ED_region_tag_redraw_no_rebuild(ar);
-
- WM_event_add_modal_handler(C, op);
-
- data->handle = WM_draw_cb_activate(CTX_wm_window(C), outliner_drag_drop_tooltip_cb, data);
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-/**
- * Notes about Outliner Item Drag 'n Drop:
- * Right now only collections display mode is supported. But ideally all/most modes would support this. There are
- * just some open design questions that have to be answered: do we want to allow mixing order of different data types
- * (like render-layers and objects)? Would that be a purely visual change or would that have any other effect? ...
- */
-static void OUTLINER_OT_item_drag_drop(wmOperatorType *ot)
-{
- ot->name = "Drag and Drop";
- ot->idname = "OUTLINER_OT_item_drag_drop";
- ot->description = "Change the hierarchical position of an item by repositioning it using drag and drop";
-
- ot->invoke = outliner_item_drag_drop_invoke;
- ot->modal = outliner_item_drag_drop_modal;
-
- ot->poll = outliner_item_drag_drop_poll;
-
- ot->flag = OPTYPE_UNDO;
-}
-
-
/* ************************** registration **********************************/
void outliner_operatortypes(void)
@@ -457,37 +110,11 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_collection_link);
WM_operatortype_append(OUTLINER_OT_collection_instance);
WM_operatortype_append(OUTLINER_OT_collection_exclude_set);
- WM_operatortype_append(OUTLINER_OT_collection_include_set);
-}
-
-static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf)
-{
- static EnumPropertyItem modal_items[] = {
- {OUTLINER_ITEM_DRAG_CANCEL, "CANCEL", 0, "Cancel", ""},
- {OUTLINER_ITEM_DRAG_CONFIRM, "CONFIRM", 0, "Confirm/Drop", ""},
- {0, NULL, 0, NULL, NULL}
- };
- const char *map_name = "Outliner Item Drag & Drop Modal Map";
-
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, map_name);
-
- /* this function is called for each spacetype, only needs to add map once */
- if (keymap && keymap->modal_items)
- return NULL;
-
- keymap = WM_modalkeymap_add(keyconf, map_name, modal_items);
-
- /* items for modal map */
- WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, OUTLINER_ITEM_DRAG_CANCEL);
- WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, OUTLINER_ITEM_DRAG_CANCEL);
-
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM);
- WM_modalkeymap_add_item(keymap, RETKEY, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM);
- WM_modalkeymap_add_item(keymap, PADENTER, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM);
-
- WM_modalkeymap_assign(keymap, "OUTLINER_OT_item_drag_drop");
-
- return keymap;
+ WM_operatortype_append(OUTLINER_OT_collection_exclude_clear);
+ WM_operatortype_append(OUTLINER_OT_collection_holdout_set);
+ WM_operatortype_append(OUTLINER_OT_collection_holdout_clear);
+ WM_operatortype_append(OUTLINER_OT_collection_indirect_only_set);
+ WM_operatortype_append(OUTLINER_OT_collection_indirect_only_clear);
}
void outliner_keymap(wmKeyConfig *keyconf)
@@ -570,12 +197,13 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_move_to_collection", MKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_link_to_collection", MKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "OUTLINER_OT_collection_exclude_set", EKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "OUTLINER_OT_collection_exclude_clear", EKEY, KM_PRESS, KM_ALT, 0);
+
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "select", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
-
- outliner_item_drag_drop_modal_keymap(keyconf);
}
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 7ab13f36953..ec5e11520a6 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -39,6 +39,7 @@
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_world_types.h"
+#include "DNA_gpencil_types.h"
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
@@ -46,9 +47,11 @@
#include "BKE_armature.h"
#include "BKE_collection.h"
#include "BKE_context.h"
+#include "BKE_gpencil.h"
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_object.h"
+#include "BKE_paint.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "BKE_workspace.h"
@@ -60,6 +63,7 @@
#include "ED_screen.h"
#include "ED_sequencer.h"
#include "ED_undo.h"
+#include "ED_gpencil.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -470,6 +474,28 @@ static eOLDrawState tree_element_active_defgroup(
return OL_DRAWSEL_NONE;
}
+static eOLDrawState UNUSED_FUNCTION(tree_element_active_gplayer)(
+ bContext *C, Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
+{
+ bGPdata *gpd = (bGPdata *)tselem->id;
+ bGPDlayer *gpl = te->directdata;
+
+ /* We can only have a single "active" layer at a time
+ * and there must always be an active layer...
+ */
+ if (set != OL_SETSEL_NONE) {
+ if (gpl) {
+ BKE_gpencil_layer_setactive(gpd, gpl);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_SELECTED, gpd);
+ }
+ }
+ else {
+ return OL_DRAWSEL_NORMAL;
+ }
+
+ return OL_DRAWSEL_NONE;
+}
+
static eOLDrawState tree_element_active_posegroup(
bContext *C, Scene *UNUSED(scene), ViewLayer *view_layer, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
{
@@ -1006,6 +1032,10 @@ static void do_outliner_item_activate_tree_element(
}
}
}
+ 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, scene, view_layer, soops, te, OL_SETSEL_NORMAL, false);
}
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 28890e42139..55a437d6ad5 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -319,112 +319,11 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s
if (outliner_animdata_test(sce->adt))
outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0);
- /* Grease Pencil */
- outliner_add_element(soops, lb, sce->gpd, te, 0, 0);
-}
-
-TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata)
-{
- struct ObjectsSelectedData *data = 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_addtail(&data->objects_selected_array, BLI_genericNodeN(te));
-
- return TRAVERSE_CONTINUE;
-}
-
-/**
- * Move objects from a collection to another.
- * We ignore the original object being inserted, we used it for polling only.
- * Instead we move all the selected objects around.
- */
-static void outliner_object_reorder(
- Main *bmain, Scene *scene,
- SpaceOops *soops,
- TreeElement *insert_element,
- TreeElement *insert_handle, TreeElementInsertType action,
- const wmEvent *event)
-{
- Collection *collection = outliner_collection_from_tree_element(insert_handle);
- Collection *collection_ob_parent = NULL;
- ID *id = insert_handle->store_elem->id;
-
- BLI_assert(action == TE_INSERT_INTO);
- UNUSED_VARS_NDEBUG(action);
-
- struct ObjectsSelectedData data = {
- .objects_selected_array = {NULL, NULL},
- };
-
- const bool is_append = event->ctrl;
-
- /* Make sure we include the originally inserted element as well. */
- TREESTORE(insert_element)->flag |= TSE_SELECTED;
-
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data);
- LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) {
- TreeElement *ten_selected = (TreeElement *)link->data;
- Object *ob = (Object *)TREESTORE(ten_selected)->id;
-
- if (is_append) {
- BKE_collection_object_add(bmain, collection, ob);
- continue;
- }
-
- /* Find parent collection of object. */
- if (ten_selected->parent) {
- for (TreeElement *te_ob_parent = ten_selected->parent; te_ob_parent; te_ob_parent = te_ob_parent->parent) {
- if (outliner_is_collection_tree_element(te_ob_parent)) {
- collection_ob_parent = outliner_collection_from_tree_element(te_ob_parent);
- break;
- }
- }
- }
- else {
- collection_ob_parent = BKE_collection_master(scene);
- }
-
- BKE_collection_object_move(bmain, scene, collection, collection_ob_parent, ob);
- }
-
- BLI_freelistN(&data.objects_selected_array);
-
- DEG_relations_tag_update(bmain);
-
- /* TODO(sergey): Use proper flag for tagging here. */
- DEG_id_tag_update(id, 0);
-
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
-}
-
-static bool outliner_object_reorder_poll(
- const TreeElement *insert_element,
- TreeElement **io_insert_handle, TreeElementInsertType *io_action)
-{
- if (outliner_is_collection_tree_element(*io_insert_handle) &&
- (insert_element->parent != *io_insert_handle))
- {
- *io_action = TE_INSERT_INTO;
- return true;
- }
-
- return false;
}
// can be inlined if necessary
static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, Object *ob)
{
- te->reinsert = outliner_object_reorder;
- te->reinsert_poll = outliner_object_reorder_poll;
-
if (outliner_animdata_test(ob->adt))
outliner_add_element(soops, &te->subtree, ob, te, TSE_ANIM_DATA, 0);
@@ -1387,80 +1286,6 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
}
}
-static void outliner_collections_reorder(
- Main *bmain,
- Scene *UNUSED(scene),
- SpaceOops *soops,
- TreeElement *insert_element,
- TreeElement *insert_handle,
- TreeElementInsertType action,
- const wmEvent *UNUSED(event))
-{
- TreeElement *from_parent_te, *to_parent_te;
- Collection *from_parent, *to_parent;
-
- Collection *collection = outliner_collection_from_tree_element(insert_element);
- Collection *relative = NULL;
- bool relative_after = false;
-
- from_parent_te = outliner_find_parent_element(&soops->tree, NULL, insert_element);
- from_parent = (from_parent_te) ? outliner_collection_from_tree_element(from_parent_te) : NULL;
-
- if (ELEM(action, TE_INSERT_BEFORE, TE_INSERT_AFTER)) {
- to_parent_te = outliner_find_parent_element(&soops->tree, NULL, insert_handle);
- to_parent = (to_parent_te) ? outliner_collection_from_tree_element(to_parent_te) : NULL;
-
- relative = outliner_collection_from_tree_element(insert_handle);
- relative_after = (action == TE_INSERT_AFTER);
- }
- else if (action == TE_INSERT_INTO) {
- to_parent = outliner_collection_from_tree_element(insert_handle);
- }
- else {
- BLI_assert(0);
- return;
- }
-
- if (!to_parent) {
- return;
- }
-
- BKE_collection_move(bmain, to_parent, from_parent, relative, relative_after, collection);
-
- DEG_relations_tag_update(bmain);
-}
-
-static bool outliner_collections_reorder_poll(
- const TreeElement *insert_element,
- TreeElement **io_insert_handle,
- TreeElementInsertType *io_action)
-{
- /* Can't move master collection. */
- Collection *collection = outliner_collection_from_tree_element(insert_element);
- if (collection->flag & COLLECTION_IS_MASTER) {
- return false;
- }
-
- /* Can only move into collections. */
- Collection *collection_handle = outliner_collection_from_tree_element(*io_insert_handle);
- if (collection_handle == NULL) {
- return false;
- }
-
- /* We can't insert/before after master collection. */
- if (collection_handle->flag & COLLECTION_IS_MASTER) {
- if (*io_action == TE_INSERT_BEFORE) {
- /* can't go higher than master collection, insert into it */
- *io_action = TE_INSERT_INTO;
- }
- else if (*io_action == TE_INSERT_AFTER) {
- *io_insert_handle = (*io_insert_handle)->subtree.last;
- }
- }
-
- return true;
-}
-
static void outliner_add_layer_collection_objects(
SpaceOops *soops, ListBase *tree, ViewLayer *layer,
LayerCollection *lc, TreeElement *ten)
@@ -1487,8 +1312,6 @@ static void outliner_add_layer_collections_recursive(
ten->name = id->name + 2;
ten->directdata = lc;
- ten->reinsert = outliner_collections_reorder;
- ten->reinsert_poll = outliner_collections_reorder_poll;
const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0;
if (exclude ||
@@ -1530,8 +1353,6 @@ BLI_INLINE void outliner_add_collection_init(TreeElement *te, Collection *collec
}
te->directdata = collection;
- te->reinsert = outliner_collections_reorder;
- te->reinsert_poll = outliner_collections_reorder_poll;
}
BLI_INLINE void outliner_add_collection_objects(
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index e4e99f88bf4..b0d63aee7c0 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -93,196 +93,6 @@ static void outliner_main_region_init(wmWindowManager *wm, ARegion *ar)
WM_event_add_dropbox_handler(&ar->handlers, lb);
}
-static bool outliner_parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
-{
- ARegion *ar = CTX_wm_region(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- float fmval[2];
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
- if (drag->type == WM_DRAG_ID) {
- ID *id = drag->poin;
- if (GS(id->name) == ID_OB) {
- /* Ensure item under cursor is valid drop target */
- TreeElement *te = outliner_dropzone_find(soops, fmval, true);
- TreeStoreElem *tselem = te ? TREESTORE(te) : NULL;
-
- if (!te) {
- /* pass */
- }
- else if (te->idcode == ID_OB && tselem->type == 0) {
- Scene *scene;
- ID *te_id = tselem->id;
-
- /* check if dropping self or parent */
- if (te_id == id || (Object *)te_id == ((Object *)id)->parent)
- return 0;
-
- /* check that parent/child are both in the same scene */
- scene = (Scene *)outliner_search_back(soops, te, ID_SCE);
-
- /* currently outliner organized in a way that if there's no parent scene
- * element for object it means that all displayed objects belong to
- * active scene and parenting them is allowed (sergey)
- */
- if (!scene) {
- return 1;
- }
- else {
- for (ViewLayer *view_layer = scene->view_layers.first;
- view_layer;
- view_layer = view_layer->next)
- {
- if (BKE_view_layer_base_find(view_layer, (Object *)id)) {
- return 1;
- }
- }
- }
- }
- }
- }
- return 0;
-}
-
-static void outliner_parent_drop_copy(wmDrag *drag, wmDropBox *drop)
-{
- ID *id = drag->poin;
-
- RNA_string_set(drop->ptr, "child", id->name + 2);
-}
-
-static bool outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event)
-{
- ARegion *ar = CTX_wm_region(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- TreeElement *te = NULL;
- float fmval[2];
-
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
- if (!ELEM(soops->outlinevis, SO_VIEW_LAYER)) {
- return false;
- }
-
- if (drag->type == WM_DRAG_ID) {
- ID *id = drag->poin;
- if (GS(id->name) == ID_OB) {
- if (((Object *)id)->parent) {
- if ((te = outliner_dropzone_find(soops, fmval, true))) {
- TreeStoreElem *tselem = TREESTORE(te);
-
- switch (te->idcode) {
- case ID_SCE:
- return (ELEM(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER));
- case ID_OB:
- return (ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE));
- /* Other codes to ignore? */
- }
- }
- return (te == NULL);
- }
- }
- }
- return 0;
-}
-
-static void outliner_parent_clear_copy(wmDrag *drag, wmDropBox *drop)
-{
- ID *id = drag->poin;
- RNA_string_set(drop->ptr, "dragged_obj", id->name + 2);
-
- /* Set to simple parent clear type. Avoid menus for drag and drop if possible.
- * If desired, user can toggle the different "Clear Parent" types in the operator
- * menu on tool shelf. */
- RNA_enum_set(drop->ptr, "type", 0);
-}
-
-static bool outliner_scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
-{
- ARegion *ar = CTX_wm_region(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- float fmval[2];
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
- if (drag->type == WM_DRAG_ID) {
- ID *id = drag->poin;
- if (GS(id->name) == ID_OB) {
- /* Ensure item under cursor is valid drop target */
- TreeElement *te = outliner_dropzone_find(soops, fmval, false);
- return (te && te->idcode == ID_SCE && TREESTORE(te)->type == 0);
- }
- }
- return 0;
-}
-
-static void outliner_scene_drop_copy(wmDrag *drag, wmDropBox *drop)
-{
- ID *id = drag->poin;
-
- RNA_string_set(drop->ptr, "object", id->name + 2);
-}
-
-static bool outliner_material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
-{
- ARegion *ar = CTX_wm_region(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- float fmval[2];
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
- if (drag->type == WM_DRAG_ID) {
- ID *id = drag->poin;
- if (GS(id->name) == ID_MA) {
- /* Ensure item under cursor is valid drop target */
- TreeElement *te = outliner_dropzone_find(soops, fmval, true);
- return (te && te->idcode == ID_OB && TREESTORE(te)->type == 0);
- }
- }
- return 0;
-}
-
-static void outliner_material_drop_copy(wmDrag *drag, wmDropBox *drop)
-{
- ID *id = drag->poin;
-
- RNA_string_set(drop->ptr, "material", id->name + 2);
-}
-
-static bool outliner_collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
-{
- ARegion *ar = CTX_wm_region(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- float fmval[2];
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
- if (drag->type == WM_DRAG_ID) {
- ID *id = drag->poin;
- if (ELEM(GS(id->name), ID_OB, ID_GR)) {
- /* Ensure item under cursor is valid drop target */
- TreeElement *te = outliner_dropzone_find(soops, fmval, true);
- return (te && outliner_is_collection_tree_element(te));
- }
- }
- return 0;
-}
-
-static void outliner_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
-{
- ID *id = drag->poin;
- RNA_string_set(drop->ptr, "child", id->name + 2);
-}
-
-/* region dropbox definition */
-static void outliner_dropboxes(void)
-{
- ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
-
- WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", outliner_parent_drop_poll, outliner_parent_drop_copy);
- WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", outliner_parent_clear_poll, outliner_parent_clear_copy);
- WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", outliner_scene_drop_poll, outliner_scene_drop_copy);
- WM_dropbox_add(lb, "OUTLINER_OT_material_drop", outliner_material_drop_poll, outliner_material_drop_copy);
- WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", outliner_collection_drop_poll, outliner_collection_drop_copy);
-}
-
static void outliner_main_region_draw(const bContext *C, ARegion *ar)
{
View2D *v2d = &ar->v2d;
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 5d2ceced904..3cd5bfc3e58 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -627,7 +627,7 @@ static void sequencer_add_cancel(bContext *UNUSED(C), wmOperator *op)
op->customdata = NULL;
}
-static bool sequencer_add_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
+static bool sequencer_add_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@@ -693,7 +693,7 @@ static void sequencer_add_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
- uiDefAutoButsRNA(layout, &ptr, sequencer_add_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
+ uiDefAutoButsRNA(layout, &ptr, sequencer_add_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index a10eda5c3e6..864609e4157 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -232,9 +232,9 @@ static void drawseqwave(View2D *v2d, const bContext *C, SpaceSeq *sseq, Scene *s
BLI_spin_lock(sound->spinlock);
if (!sound->waveform) {
- if (!(sound->flags & SOUND_FLAGS_WAVEFORM_LOADING)) {
+ if (!(sound->tags & SOUND_TAGS_WAVEFORM_LOADING)) {
/* prevent sounds from reloading */
- sound->flags |= SOUND_FLAGS_WAVEFORM_LOADING;
+ sound->tags |= SOUND_TAGS_WAVEFORM_LOADING;
BLI_spin_unlock(sound->spinlock);
sequencer_preview_add_sound(C, seq);
}
@@ -267,7 +267,7 @@ static void drawseqwave(View2D *v2d, const bContext *C, SpaceSeq *sseq, Scene *s
GPU_blend(true);
- immBegin(GWN_PRIM_TRI_STRIP, length * 2);
+ immBegin(GPU_PRIM_TRI_STRIP, length * 2);
for (i = 0; i < length; i++) {
float sampleoffset = startsample + ((x1_offset - x1) / stepsize + i) * samplestep;
@@ -343,7 +343,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
col[3] = 196; /* alpha, used for all meta children */
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -457,7 +457,7 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
immUniformColor4ub(0, 0, 0, 50);
}
- immBegin(GWN_PRIM_TRIS, 3);
+ immBegin(GPU_PRIM_TRIS, 3);
immVertex2fv(pos, v1);
immVertex2fv(pos, v2);
immVertex2fv(pos, v3);
@@ -719,7 +719,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
x2 = (seq->endstill) ? (seq->start + seq->len) : seq->enddisp;
y2 = seq->machine + SEQ_STRIP_OFSTOP;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -781,7 +781,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
if (seq->flag & SEQ_LOCK) {
GPU_blend(true);
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_DIAG_STRIPES);
immUniform4f("color1", 1.0f, 1.0f, 1.0f, 0.125f);
@@ -799,7 +799,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
if (!BKE_sequence_is_valid_check(seq)) {
GPU_blend(true);
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_DIAG_STRIPES);
immUniform4f("color1", 1.0f, 0.0f, 0.0f, 1.0f);
@@ -834,7 +834,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
drawmeta_contents(scene, seq, x1, y1, x2, y2);
}
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
/* TODO: add back stippled line for muted strips? */
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1040,7 +1040,7 @@ static void sequencer_draw_borders(const SpaceSeq *sseq, const View2D *v2d, cons
GPU_line_width(1.0f);
/* border */
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -1230,9 +1230,9 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
/* Format needs to be created prior to any immBindProgram call.
* Do it here because OCIO binds it's own shader.
*/
- Gwn_VertFormat *imm_format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(imm_format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint texCoord = GWN_vertformat_attr_add(imm_format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ GPUVertFormat *imm_format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint texCoord = GPU_vertformat_attr_add(imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (scope) {
IMB_freeImBuf(ibuf);
@@ -1308,8 +1308,8 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
if (draw_backdrop) {
/* XXX: need to load identity projection too? */
- gpuPushMatrix();
- gpuLoadIdentity();
+ GPU_matrix_push();
+ GPU_matrix_identity_set();
}
glGenTextures(1, (GLuint *)&texid);
@@ -1331,7 +1331,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
immUniform1i("image", 0);
}
- immBegin(GWN_PRIM_TRI_FAN, 4);
+ immBegin(GPU_PRIM_TRI_FAN, 4);
if (draw_overlay) {
if (sseq->overlay_type == SEQ_DRAW_OVERLAY_RECT) {
@@ -1439,7 +1439,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
}
if (draw_backdrop) {
- gpuPopMatrix();
+ GPU_matrix_pop();
return;
}
@@ -1514,7 +1514,7 @@ static void draw_seq_backdrop(View2D *v2d)
{
int i;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* darker gray overlay over the view backdrop */
@@ -1541,7 +1541,7 @@ static void draw_seq_backdrop(View2D *v2d)
i = max_ii(1, ((int)v2d->cur.ymin) - 1);
int line_len = (int)v2d->cur.ymax - i + 1;
immUniformThemeColor(TH_GRID);
- immBegin(GWN_PRIM_LINES, line_len * 2);
+ immBegin(GPU_PRIM_LINES, line_len * 2);
while (line_len--) {
immVertex2f(pos, v2d->cur.xmax, i);
immVertex2f(pos, v2d->cur.xmin, i);
@@ -1593,7 +1593,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
const Sequence *seq = special_seq_update;
GPU_blend(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ub(255, 255, 255, 48);
@@ -1613,7 +1613,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
GPU_blend(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* draw darkened area outside of active timeline
@@ -1631,7 +1631,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
immUniformThemeColorShade(TH_BACK, -60);
/* thin lines where the actual frames are */
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, frame_sta, v2d->cur.ymin);
immVertex2f(pos, frame_sta, v2d->cur.ymax);
@@ -1649,7 +1649,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
immUniformThemeColorShade(TH_BACK, -40);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, ms->disp_range[0], v2d->cur.ymin);
immVertex2f(pos, ms->disp_range[0], v2d->cur.ymax);
@@ -1735,12 +1735,12 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
if (scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) {
int cfra_over = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ? scene->ed->over_cfra : scene->r.cfra + scene->ed->over_ofs;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3f(0.2f, 0.2f, 0.2f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, cfra_over, v2d->cur.ymin);
immVertex2f(pos, cfra_over, v2d->cur.ymax);
immEnd();
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index cefc6cdd814..199ff06cc8b 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -739,7 +739,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
if (!skip_dup) {
/* Duplicate AFTER the first change */
- seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
+ seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_ANIM);
}
if (seqn) {
@@ -848,7 +848,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
if (!skip_dup) {
/* Duplicate AFTER the first change */
- seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
+ seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_ANIM);
}
if (seqn) {
@@ -2091,6 +2091,7 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op)
SEQP_BEGIN (ed, seq)
{
+ BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq);
if (seq->seq1 || seq->seq2 || seq->seq3) {
BKE_sequence_calc(scene, seq);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_preview.c b/source/blender/editors/space_sequencer/sequencer_preview.c
index c58c05b67c0..ae011e48538 100644
--- a/source/blender/editors/space_sequencer/sequencer_preview.c
+++ b/source/blender/editors/space_sequencer/sequencer_preview.c
@@ -96,7 +96,7 @@ static void preview_startjob(void *data, short *stop, short *do_update, float *p
/* make sure we cleanup the loading flag! */
BLI_spin_lock(sound->spinlock);
- sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+ sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
BLI_spin_unlock(sound->spinlock);
BLI_mutex_lock(pj->mutex);
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 8fb526bf502..11517d64d7a 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -366,7 +366,7 @@ static void sequencer_listener(
/* ************* dropboxes ************* */
-static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
+static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip))
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -380,7 +380,7 @@ static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
return 0;
}
-static bool movie_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
+static bool movie_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip))
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -393,7 +393,7 @@ static bool movie_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
return 0;
}
-static bool sound_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
+static bool sound_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip))
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index ac43d7de408..f3c55aa3474 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -474,7 +474,7 @@ static void text_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
/* ************* dropboxes ************* */
-static bool text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
@@ -491,18 +491,15 @@ static void text_drop_copy(wmDrag *drag, wmDropBox *drop)
RNA_string_set(drop->ptr, "filepath", drag->path);
}
-static bool text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
- if (drag->type == WM_DRAG_ID)
- return true;
-
- return false;
+ return (drag->type == WM_DRAG_ID);
}
static void text_drop_paste(wmDrag *drag, wmDropBox *drop)
{
char *text;
- ID *id = drag->poin;
+ ID *id = WM_drag_ID(drag, 0);
/* copy drag path to properties */
text = RNA_path_full_ID_py(id);
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 748a5c05ef1..aa499d52589 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -913,7 +913,7 @@ static void draw_textscroll(const SpaceText *st, rcti *scroll, rcti *back)
float rad;
/* background so highlights don't go behind the scrollbar */
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_BACK);
immRecti(pos, back->xmin, back->ymin, back->xmax, back->ymax);
@@ -967,24 +967,24 @@ static void draw_documentation(const SpaceText *st, ARegion *ar)
boxh = (DOC_HEIGHT + 1) * (st->lheight_dpi + TXT_LINE_SPACING);
/* Draw panel */
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_BACK);
immRecti(pos, x, y, x + boxw, y - boxh);
immUniformThemeColor(TH_SHADE1);
- immBegin(GWN_PRIM_LINE_LOOP, 4);
+ immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex2i(pos, x, y);
immVertex2i(pos, x + boxw, y);
immVertex2i(pos, x + boxw, y - boxh);
immVertex2i(pos, x, y - boxh);
immEnd();
- immBegin(GWN_PRIM_LINE_LOOP, 3);
+ immBegin(GPU_PRIM_LINE_LOOP, 3);
immVertex2i(pos, x + boxw - 10, y - 7);
immVertex2i(pos, x + boxw - 4, y - 7);
immVertex2i(pos, x + boxw - 7, y - 2);
immEnd();
- immBegin(GWN_PRIM_LINE_LOOP, 3);
+ immBegin(GPU_PRIM_LINE_LOOP, 3);
immVertex2i(pos, x + boxw - 10, y - boxh + 7);
immVertex2i(pos, x + boxw - 4, y - boxh + 7);
immVertex2i(pos, x + boxw - 7, y - boxh + 2);
@@ -1066,7 +1066,7 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc
/* not needed but stands out nicer */
UI_draw_box_shadow(220, x, y - boxh, x + boxw, y);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_SHADE1);
@@ -1089,7 +1089,7 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc
w = st->cwidth * text_get_char_pos(st, str, len);
if (item == sel) {
- uint posi = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint posi = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_SHADE2);
@@ -1130,7 +1130,7 @@ static void draw_text_decoration(SpaceText *st, ARegion *ar)
return;
}
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* Draw the selection */
@@ -1443,7 +1443,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
if (st->showlinenrs) {
x = TXT_OFFSET + TEXTXLOC;
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_GRID);
immRecti(pos, (TXT_OFFSET - 12), 0, (TXT_OFFSET - 5) + TEXTXLOC, ar->winy - 2);
@@ -1502,7 +1502,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
margin_column_x = x + st->cwidth * (st->margin_column - st->left);
if (margin_column_x >= x) {
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -1515,7 +1515,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
immUniform1f("dash_width", 2.0f);
immUniform1f("dash_factor", 0.5f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2i(shdr_pos, margin_column_x, 0);
immVertex2i(shdr_pos, margin_column_x, ar->winy - 2);
immEnd();
diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c
index e45159124e8..6113922c02e 100644
--- a/source/blender/editors/space_topbar/space_topbar.c
+++ b/source/blender/editors/space_topbar/space_topbar.c
@@ -168,6 +168,10 @@ static void topbar_main_region_listener(wmWindow *UNUSED(win), ScrArea *UNUSED(s
if (wmn->data == ND_SPACE_VIEW3D)
ED_region_tag_redraw(ar);
break;
+ case NC_GPENCIL:
+ if (wmn->data == ND_DATA)
+ ED_region_tag_redraw(ar);
+ break;
}
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index beb323fb21c..3649c6f6dbb 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -80,6 +80,7 @@
#include "BKE_subsurf.h"
#include "BKE_unit.h"
#include "BKE_tracking.h"
+#include "BKE_gpencil.h"
#include "BKE_editmesh.h"
@@ -121,10 +122,10 @@
int view3d_effective_drawtype(const struct View3D *v3d)
{
- if (v3d->drawtype == OB_RENDER) {
- return v3d->prev_drawtype;
+ if (v3d->shading.type == OB_RENDER) {
+ return v3d->shading.prev_type;
}
- return v3d->drawtype;
+ return v3d->shading.type;
}
static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
@@ -139,10 +140,10 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
return true;
/* if its drawing textures with zbuf sel, then don't draw dots */
- if (dt == OB_TEXTURE && vd->drawtype == OB_TEXTURE)
+ if (dt == OB_TEXTURE && vd->shading.type == OB_TEXTURE)
return false;
- if ((vd->drawtype >= OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX))
+ if ((vd->shading.type >= OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX))
return false;
return true;
@@ -244,7 +245,7 @@ void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], un
circball_array_fill(verts, cent, rad, tmat);
- immBegin(GWN_PRIM_LINE_LOOP, CIRCLE_RESOL);
+ immBegin(GPU_PRIM_LINE_LOOP, CIRCLE_RESOL);
for (int i = 0; i < CIRCLE_RESOL; ++i) {
immVertex3fv(pos, verts[i]);
}
@@ -285,15 +286,15 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
if (imm_len == 0) return;
- Gwn_VertFormat *format = immVertexFormat();
- data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
+ GPUVertFormat *format = immVertexFormat();
+ data.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ data.col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U32, 1, GPU_FETCH_INT);
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
- immBeginAtMost(GWN_PRIM_POINTS, imm_len);
+ immBeginAtMost(GPU_PRIM_POINTS, imm_len);
dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data, DM_FOREACH_NOP);
immEnd();
@@ -303,9 +304,9 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *UNUSED(dm), int offset)
{
Mesh *me = ob->data;
- Gwn_Batch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
- GWN_batch_draw(batch);
+ GPUBatch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GPU_batch_draw(batch);
}
#endif
@@ -328,15 +329,15 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset)
drawBMOffset_userData data;
data.bm = em->bm;
data.offset = offset;
- Gwn_VertFormat *format = immVertexFormat();
- data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
+ GPUVertFormat *format = immVertexFormat();
+ data.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ data.col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U32, 1, GPU_FETCH_INT);
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
- immBeginAtMost(GWN_PRIM_POINTS, em->bm->totvert);
+ immBeginAtMost(GPU_PRIM_POINTS, em->bm->totvert);
dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, &data, DM_FOREACH_NOP);
immEnd();
@@ -348,9 +349,9 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset)
GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
Mesh *me = em->ob->data;
- Gwn_Batch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
- GWN_batch_draw(batch);
+ GPUBatch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GPU_batch_draw(batch);
}
#endif
@@ -375,20 +376,20 @@ static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset)
data.bm = em->bm;
data.offset = offset;
- Gwn_VertFormat *format = immVertexFormat();
+ GPUVertFormat *format = immVertexFormat();
const int imm_len = dm->getNumEdges(dm) * 2;
if (imm_len == 0) return;
- data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
+ data.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ data.col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U32, 1, GPU_FETCH_INT);
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
GPU_line_width(1.0f);
- immBeginAtMost(GWN_PRIM_LINES, imm_len);
+ immBeginAtMost(GPU_PRIM_LINES, imm_len);
dm->foreachMappedEdge(dm, bbs_mesh_wire__mapFunc, &data);
immEnd();
@@ -400,9 +401,9 @@ static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset)
GPU_line_width(1.0f);
Mesh *me = em->ob->data;
- Gwn_Batch *batch = DRW_mesh_batch_cache_get_edges_with_select_id(me, offset);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
- GWN_batch_draw(batch);
+ GPUBatch *batch = DRW_mesh_batch_cache_get_edges_with_select_id(me, offset);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GPU_batch_draw(batch);
}
#endif
@@ -420,13 +421,13 @@ static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *dm, const bool use_select
if (imm_len == 0) return;
- Gwn_VertFormat *format = immVertexFormat();
- data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
+ GPUVertFormat *format = immVertexFormat();
+ data.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ data.col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U32, 1, GPU_FETCH_INT);
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
- immBeginAtMost(GWN_PRIM_TRIS, imm_len);
+ immBeginAtMost(GPU_PRIM_TRIS, imm_len);
if (use_select == false) {
int selcol;
@@ -463,20 +464,20 @@ static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *dm, const bool use_select
static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *UNUSED(dm), const bool use_select)
{
Mesh *me = em->ob->data;
- Gwn_Batch *batch;
+ GPUBatch *batch;
if (use_select) {
batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
- GWN_batch_draw(batch);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GPU_batch_draw(batch);
}
else {
int selcol;
GPU_select_index_get(0, &selcol);
batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
- GWN_batch_uniform_1ui(batch, "color", selcol);
- GWN_batch_draw(batch);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
+ GPU_batch_uniform_1ui(batch, "color", selcol);
+ GPU_batch_draw(batch);
}
}
#endif
@@ -499,15 +500,15 @@ static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *dm)
{
drawBMOffset_userData data; /* don't use offset */
data.bm = em->bm;
- Gwn_VertFormat *format = immVertexFormat();
- data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
+ GPUVertFormat *format = immVertexFormat();
+ data.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ data.col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U32, 1, GPU_FETCH_INT);
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
GPU_point_size(UI_GetThemeValuef(TH_FACEDOT_SIZE));
- immBeginAtMost(GWN_PRIM_POINTS, em->bm->totface);
+ immBeginAtMost(GPU_PRIM_POINTS, em->bm->totface);
dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, &data, DM_FOREACH_NOP);
immEnd();
@@ -517,9 +518,9 @@ static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *dm)
static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *UNUSED(dm))
{
Mesh *me = em->ob->data;
- Gwn_Batch *batch = DRW_mesh_batch_cache_get_facedots_with_select_id(me, 1);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
- GWN_batch_draw(batch);
+ GPUBatch *batch = DRW_mesh_batch_cache_get_facedots_with_select_id(me, 1);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GPU_batch_draw(batch);
}
#endif
@@ -583,12 +584,12 @@ static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(sce
{
int selcol;
- Gwn_Batch *batch;
+ GPUBatch *batch;
GPU_select_index_get(0, &selcol);
batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
- GWN_batch_uniform_1ui(batch, "color", selcol);
- GWN_batch_draw(batch);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
+ GPU_batch_uniform_1ui(batch, "color", selcol);
+ GPU_batch_draw(batch);
}
G.f |= (G_f_orig & G_BACKBUFSEL);
@@ -601,15 +602,15 @@ static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(sce
static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob)
{
Mesh *me = ob->data;
- Gwn_Batch *batch;
+ GPUBatch *batch;
if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
}
else {
batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false, 1);
}
- GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
- GWN_batch_draw(batch);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GPU_batch_draw(batch);
}
void draw_object_backbufsel(
@@ -621,7 +622,7 @@ void draw_object_backbufsel(
select_mode = ts->selectmode;
}
- gpuMultMatrix(ob->obmat);
+ GPU_matrix_mul(ob->obmat);
glClearDepth(1.0); GPU_clear(GPU_DEPTH_BIT);
GPU_depth_test(true);
@@ -688,7 +689,7 @@ void draw_object_backbufsel(
break;
}
- gpuLoadMatrix(rv3d->viewmat);
+ GPU_matrix_set(rv3d->viewmat);
}
@@ -747,8 +748,8 @@ void ED_draw_object_facemap(
Mesh *me = ob->data;
const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
if (facemap_data) {
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(col);
@@ -788,7 +789,7 @@ void ED_draw_object_facemap(
/* use gawain immediate mode fore now */
const int looptris_len = poly_to_tri_count(mpoly_len, mloop_len);
- immBeginAtMost(GWN_PRIM_TRIS, looptris_len * 3);
+ immBeginAtMost(GPU_PRIM_TRIS, looptris_len * 3);
MPoly *mp;
int i;
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 6d4009e9d2b..98c5c4e604d 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -36,6 +36,7 @@
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_gpencil_types.h"
#include "MEM_guardedalloc.h"
@@ -251,7 +252,7 @@ void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d)
/* we have to multiply instead of loading viewmatob to make
* it work with duplis using displists, otherwise it will
* override the dupli-matrix */
- gpuMultMatrix(ob->obmat);
+ GPU_matrix_mul(ob->obmat);
}
#ifdef DEBUG
@@ -293,7 +294,7 @@ void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa)
{
wmWindowManager *wm = bmain->wm.first;
- if (v3d->drawtype != OB_RENDER) {
+ if (v3d->shading.type != OB_RENDER) {
ARegion *ar;
for (ar = sa->regionbase.first; ar; ar = ar->next) {
@@ -324,14 +325,7 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene)
v3d->grid = 1.0f;
v3d->gridlines = 16;
v3d->gridsubdiv = 10;
- v3d->drawtype = OB_SOLID;
- v3d->shading.flag = V3D_SHADING_SPECULAR_HIGHLIGHT;
- v3d->shading.light = V3D_LIGHTING_STUDIO;
- v3d->shading.shadow_intensity = 0.5f;
- v3d->shading.xray_alpha = 0.5f;
- v3d->shading.cavity_valley_factor = 1.0f;
- v3d->shading.cavity_ridge_factor = 1.0f;
- copy_v3_fl(v3d->shading.single_color, 0.8f);
+ BKE_screen_view3d_shading_init(&v3d->shading);
v3d->overlay.wireframe_threshold = 0.5f;
v3d->overlay.bone_select_alpha = 0.5f;
@@ -342,12 +336,18 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene)
v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR;
v3d->flag = V3D_SELECT_OUTLINE;
- v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL;
+ v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_ANNOTATION;
v3d->lens = 50.0f;
v3d->near = 0.01f;
v3d->far = 1000.0f;
+ v3d->overlay.gpencil_grid_scale = 1.0; // Scales
+ v3d->overlay.gpencil_grid_lines = GP_DEFAULT_GRID_LINES; // NUmber of Lines
+ v3d->overlay.gpencil_paper_opacity = 0.5f;
+ v3d->overlay.gpencil_grid_axis = V3D_GP_GRID_AXIS_Y;
+ v3d->overlay.gpencil_grid_opacity = 0.9f;
+
v3d->bundle_size = 0.2f;
v3d->bundle_drawtype = OB_PLAINAXES;
@@ -357,6 +357,10 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene)
v3d->stereo3d_convergence_alpha = 0.15f;
v3d->stereo3d_volume_alpha = 0.05f;
+ /* grease pencil settings */
+ v3d->vertex_opacity = 1.0f;
+ v3d->gp_flag |= V3D_GP_SHOW_EDIT_LINES;
+
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for view3d");
@@ -431,8 +435,8 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
v3dn->lay = v3do->localvd->lay & 0xFFFFFF;
}
- if (v3dn->drawtype == OB_RENDER)
- v3dn->drawtype = OB_SOLID;
+ if (v3dn->shading.type == OB_RENDER)
+ v3dn->shading.type = OB_SOLID;
/* copy or clear inside new stuff */
@@ -550,48 +554,29 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *ar)
}
}
-static bool view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
- if (drag->type == WM_DRAG_ID) {
- ID *id = drag->poin;
- if (GS(id->name) == ID_OB)
- return 1;
- }
- return 0;
+ return WM_drag_ID(drag, ID_OB) != NULL;
}
-static bool view3d_collection_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool view3d_collection_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
- if (drag->type == WM_DRAG_ID) {
- ID *id = drag->poin;
- if (GS(id->name) == ID_GR)
- return 1;
- }
- return 0;
+ return WM_drag_ID(drag, ID_GR) != NULL;
}
-static bool view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
- if (drag->type == WM_DRAG_ID) {
- ID *id = drag->poin;
- if (GS(id->name) == ID_MA)
- return 1;
- }
- return 0;
+ return WM_drag_ID(drag, ID_MA) != NULL;
}
-static bool view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
{
- if (drag->type == WM_DRAG_ID) {
- ID *id = drag->poin;
- if (GS(id->name) == ID_IM)
- return 1;
+ if (drag->type == WM_DRAG_PATH) {
+ return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)); /* rule might not work? */
}
- else if (drag->type == WM_DRAG_PATH) {
- if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)) /* rule might not work? */
- return 1;
+ else {
+ return WM_drag_ID(drag, ID_IM) != NULL;
}
- return 0;
}
static bool view3d_ima_bg_is_camera_view(bContext *C)
@@ -606,19 +591,19 @@ static bool view3d_ima_bg_is_camera_view(bContext *C)
return false;
}
-static bool view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
+static bool view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **tooltip)
{
if (view3d_ima_bg_is_camera_view(C)) {
return true;
}
if (!ED_view3d_give_base_under_cursor(C, event->mval)) {
- return view3d_ima_drop_poll(C, drag, event);
+ return view3d_ima_drop_poll(C, drag, event, tooltip);
}
return 0;
}
-static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
+static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **tooltip)
{
if (!view3d_ima_bg_is_camera_view(C)) {
return true;
@@ -630,31 +615,31 @@ static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent
if ((base == NULL) ||
((base != NULL) && base->object->type == OB_EMPTY))
{
- return view3d_ima_drop_poll(C, drag, event);
+ return view3d_ima_drop_poll(C, drag, event, tooltip);
}
return 0;
}
-static bool view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
+static bool view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **tooltip)
{
Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
if (base && base->object->type == OB_MESH)
- return view3d_ima_drop_poll(C, drag, event);
+ return view3d_ima_drop_poll(C, drag, event, tooltip);
return 0;
}
static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = drag->poin;
+ ID *id = WM_drag_ID(drag, ID_OB);
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = drag->poin;
+ ID *id = WM_drag_ID(drag, ID_GR);
drop->opcontext = WM_OP_EXEC_DEFAULT;
RNA_string_set(drop->ptr, "name", id->name + 2);
@@ -662,14 +647,14 @@ static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = drag->poin;
+ ID *id = WM_drag_ID(drag, 0);
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = drag->poin;
+ ID *id = WM_drag_ID(drag, 0);
if (id) {
RNA_string_set(drop->ptr, "name", id->name + 2);
@@ -716,26 +701,26 @@ static void view3d_dropboxes(void)
static void view3d_widgets(void)
{
- wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure(
+ wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(
&(const struct wmGizmoMapType_Params){SPACE_VIEW3D, RGN_TYPE_WINDOW});
- WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_spot);
- WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_area);
- WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_target);
- WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_force_field);
- WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera);
- WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera_view);
- WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_empty_image);
- WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_armature_spline);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_lamp_spot);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_lamp_area);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_lamp_target);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_force_field);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera_view);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_empty_image);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_armature_spline);
- WM_gizmogrouptype_append(TRANSFORM_WGT_gizmo);
- WM_gizmogrouptype_append(VIEW3D_WGT_xform_cage);
+ WM_gizmogrouptype_append(TRANSFORM_GGT_gizmo);
+ WM_gizmogrouptype_append(VIEW3D_GGT_xform_cage);
- WM_gizmogrouptype_append(VIEW3D_WGT_ruler);
- WM_gizmotype_append(VIEW3D_WT_ruler_item);
+ WM_gizmogrouptype_append(VIEW3D_GGT_ruler);
+ WM_gizmotype_append(VIEW3D_GT_ruler_item);
- WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_navigate);
- WM_gizmotype_append(VIEW3D_WT_navigate_rotate);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_navigate);
+ WM_gizmotype_append(VIEW3D_GT_navigate_rotate);
}
@@ -815,13 +800,13 @@ static void view3d_main_region_listener(
{
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
- wmGizmoMap *mmap = ar->gizmo_map;
+ wmGizmoMap *gzmap = ar->gizmo_map;
/* context changes */
switch (wmn->category) {
case NC_WM:
if (ELEM(wmn->data, ND_UNDO)) {
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
}
break;
case NC_ANIMATION:
@@ -848,14 +833,14 @@ static void view3d_main_region_listener(
if (wmn->reference)
view3d_recalc_used_layers(ar, wmn, wmn->reference);
ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
break;
case ND_LAYER:
if (wmn->reference) {
BKE_screen_view3d_sync(v3d, wmn->reference);
}
ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
break;
case ND_OB_ACTIVE:
case ND_OB_SELECT:
@@ -867,7 +852,7 @@ static void view3d_main_region_listener(
case ND_MARKERS:
case ND_MODE:
ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
break;
case ND_WORLD:
/* handled by space_view3d_listener() for v3d access */
@@ -899,7 +884,7 @@ static void view3d_main_region_listener(
case ND_POINTCACHE:
case ND_LOD:
ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
break;
}
switch (wmn->action) {
@@ -912,7 +897,7 @@ static void view3d_main_region_listener(
switch (wmn->data) {
case ND_SELECT:
{
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
ATTR_FALLTHROUGH;
}
case ND_DATA:
@@ -993,7 +978,7 @@ static void view3d_main_region_listener(
break;
case ND_LIGHTING_DRAW:
ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
break;
}
break;
@@ -1019,7 +1004,7 @@ static void view3d_main_region_listener(
rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
}
ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
}
break;
case NC_ID:
@@ -1035,7 +1020,7 @@ static void view3d_main_region_listener(
case ND_LAYOUTBROWSE:
case ND_LAYOUTDELETE:
case ND_LAYOUTSET:
- WM_gizmomap_tag_refresh(mmap);
+ WM_gizmomap_tag_refresh(gzmap);
ED_region_tag_redraw(ar);
break;
case ND_LAYER:
@@ -1413,7 +1398,7 @@ static void space_view3d_listener(
switch (wmn->data) {
case ND_WORLD_DRAW:
case ND_WORLD:
- if (v3d->flag3 & V3D_SHOW_WORLD)
+ if (v3d->shading.background_type & V3D_SHADING_BACKGROUND_WORLD)
ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
break;
}
@@ -1421,7 +1406,7 @@ static void space_view3d_listener(
case NC_MATERIAL:
switch (wmn->data) {
case ND_NODES:
- if (v3d->drawtype == OB_TEXTURE)
+ if (v3d->shading.type == OB_TEXTURE)
ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
break;
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 8fa327d8782..38fac7cb37d 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -60,6 +60,7 @@
#include "BKE_deform.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
+#include "BKE_report.h"
#include "DEG_depsgraph.h"
@@ -1223,10 +1224,14 @@ void VIEW3D_OT_properties(wmOperatorType *ot)
ot->flag = 0;
}
-static int view3d_object_mode_menu(bContext *C, wmOperator *UNUSED(op))
+static int view3d_object_mode_menu(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
- if (ob && ((ob->mode & OB_MODE_EDIT) == 0) && (ELEM(ob->type, OB_ARMATURE))) {
+ if (ob == NULL) {
+ BKE_report(op->reports, RPT_WARNING, "No active object found");
+ return OPERATOR_CANCELLED;
+ }
+ else if (((ob->mode & OB_MODE_EDIT) == 0) && (ELEM(ob->type, OB_ARMATURE))) {
ED_object_mode_toggle(C, OB_MODE_POSE);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index be79cef182d..46b53a369e3 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -184,8 +184,8 @@ static void view3d_main_region_setup_view(
ED_view3d_update_viewmat(depsgraph, scene, v3d, ar, viewmat, winmat, rect);
/* set for opengl */
- gpuLoadProjectionMatrix(rv3d->winmat);
- gpuLoadMatrix(rv3d->viewmat);
+ GPU_matrix_projection_set(rv3d->winmat);
+ GPU_matrix_set(rv3d->viewmat);
}
static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d)
@@ -365,7 +365,7 @@ static void drawviewborder_grid3(uint shdr_pos, float x1, float x2, float y1, fl
x4 = x1 + (1.0f - fac) * (x2 - x1);
y4 = y1 + (1.0f - fac) * (y2 - y1);
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
immVertex2f(shdr_pos, x1, y3);
immVertex2f(shdr_pos, x2, y3);
@@ -390,7 +390,7 @@ static void drawviewborder_triangle(
float w = x2 - x1;
float h = y2 - y1;
- immBegin(GWN_PRIM_LINES, 6);
+ immBegin(GPU_PRIM_LINES, 6);
if (w > h) {
if (golden) {
@@ -467,7 +467,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View
x2i = (int)(x2 + (1.0f - 0.0001f));
y2i = (int)(y2 + (1.0f - 0.0001f));
- uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
/* First, solid lines. */
{
@@ -559,7 +559,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View
x3 = x1 + 0.5f * (x2 - x1);
y3 = y1 + 0.5f * (y2 - y1);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(shdr_pos, x1, y3);
immVertex2f(shdr_pos, x2, y3);
@@ -571,7 +571,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View
}
if (ca->dtx & CAM_DTX_CENTER_DIAG) {
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
immVertex2f(shdr_pos, x1, y1);
immVertex2f(shdr_pos, x2, y2);
@@ -674,7 +674,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View
static void drawrenderborder(ARegion *ar, View3D *v3d)
{
/* use the same program for everything */
- uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
GPU_line_width(1.0f);
@@ -814,12 +814,12 @@ static void draw_view_axis(RegionView3D *rv3d, const rcti *rect)
GPU_blend(true);
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GWN_PRIM_LINES, 6);
+ immBegin(GPU_PRIM_LINES, 6);
for (int axis_i = 0; axis_i < 3; axis_i++) {
int i = axis_order[axis_i];
@@ -859,9 +859,9 @@ static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d)
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_FALSE); /* don't overwrite zbuf */
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
@@ -872,7 +872,7 @@ static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d)
mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale);
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
color[3] = 0; /* more transparent toward the ends */
immAttrib4ubv(col, color);
add_v3_v3v3(end, o, scaled_axis);
@@ -911,7 +911,7 @@ static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d)
axis_angle_to_quat(q, vis_axis, vis_angle);
}
- immBegin(GWN_PRIM_LINE_LOOP, ROT_AXIS_DETAIL);
+ immBegin(GPU_PRIM_LINE_LOOP, ROT_AXIS_DETAIL);
color[3] = 63; /* somewhat faint */
immAttrib4ubv(col, color);
float angle = 0.0f;
@@ -940,7 +940,7 @@ static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d)
/* -- draw rotation center -- */
immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
GPU_point_size(5.0f);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immAttrib4ubv(col, color);
immVertex3fv(pos, o);
immEnd();
@@ -1207,7 +1207,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int UNUSED(of
if ((U.uiflag & USER_SHOW_GIZMO_AXIS) ||
(v3d->flag2 & V3D_RENDER_OVERRIDE) ||
/* No need to display gizmo and this info. */
- (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE)))
+ (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE)))
{
/* pass */
}
@@ -1355,10 +1355,10 @@ void ED_view3d_draw_offscreen(
GPU_free_images_anim(G.main); /* XXX :((( */
}
- gpuPushProjectionMatrix();
- gpuLoadIdentity();
- gpuPushMatrix();
- gpuLoadIdentity();
+ GPU_matrix_push_projection();
+ GPU_matrix_identity_set();
+ GPU_matrix_push();
+ GPU_matrix_identity_set();
if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera)
view3d_stereo3d_setup_offscreen(depsgraph, scene, v3d, ar, winmat, viewname);
@@ -1375,8 +1375,8 @@ void ED_view3d_draw_offscreen(
ar->winy = bwiny;
ar->winrct = brect;
- gpuPopProjectionMatrix();
- gpuPopMatrix();
+ GPU_matrix_pop_projection();
+ GPU_matrix_pop();
UI_Theme_Restore(&theme_state);
@@ -1412,6 +1412,12 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
ofs = NULL;
}
+ GPUFrameBuffer *old_fb = GPU_framebuffer_active_get();
+
+ if (old_fb) {
+ GPU_framebuffer_restore();
+ }
+
const bool own_ofs = (ofs == NULL);
DRW_opengl_context_enable();
@@ -1556,6 +1562,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
DRW_opengl_context_disable();
+ if (old_fb) {
+ GPU_framebuffer_bind(old_fb);
+ }
+
if (ibuf->rect_float && ibuf->rect)
IMB_rect_from_float(ibuf);
@@ -1589,17 +1599,17 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
v3d.camera = camera;
v3d.lay = scene->lay;
- v3d.drawtype = drawtype;
+ v3d.shading.type = drawtype;
v3d.flag2 = V3D_RENDER_OVERRIDE;
if (draw_flags & V3D_OFSDRAW_USE_GPENCIL) {
- v3d.flag2 |= V3D_SHOW_GPENCIL;
+ v3d.flag2 |= V3D_SHOW_ANNOTATION;
}
if (draw_flags & V3D_OFSDRAW_USE_SOLID_TEX) {
v3d.flag2 |= V3D_SOLID_TEX;
}
- v3d.flag3 |= V3D_SHOW_WORLD;
+ v3d.shading.background_type = V3D_SHADING_BACKGROUND_WORLD;
if (draw_flags & V3D_OFSDRAW_USE_CAMERA_DOF) {
if (camera->type == OB_CAMERA) {
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index cfeb199de15..45e4c4b4676 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -179,7 +179,7 @@ static void backdrawview3d(
}
/* texture paint mode sampling */
else if (obact_eval && (obact_eval->mode & OB_MODE_TEXTURE_PAINT) &&
- (v3d->drawtype > OB_WIRE))
+ (v3d->shading.type > OB_WIRE))
{
/* do nothing */
}
@@ -211,7 +211,7 @@ static void backdrawview3d(
#endif
#if 0 /* v3d->zbuf deprecated */
- if (v3d->drawtype > OB_WIRE) v3d->zbuf = true;
+ if (v3d->shading.type > OB_WIRE) v3d->zbuf = true;
#endif
/* dithering and AA break color coding, so disable */
@@ -685,13 +685,13 @@ static void view3d_draw_bgpic(Scene *scene, Depsgraph *depsgraph,
GPU_blend(true);
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- gpuPushProjectionMatrix();
- gpuPushMatrix();
+ GPU_matrix_push_projection();
+ GPU_matrix_push();
ED_region_pixelspace(ar);
- gpuTranslate2f(centx, centy);
- gpuScaleUniform(bgpic->scale);
- gpuRotate2D(RAD2DEGF(-bgpic->rotation));
+ GPU_matrix_translate_2f(centx, centy);
+ GPU_matrix_scale_1f(bgpic->scale);
+ GPU_matrix_rotate_2d(RAD2DEGF(-bgpic->rotation));
if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) {
zoomx *= -1.0f;
@@ -707,8 +707,8 @@ static void view3d_draw_bgpic(Scene *scene, Depsgraph *depsgraph,
immDrawPixelsTex(&state, x1 - centx, y1 - centy, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect,
zoomx, zoomy, col);
- gpuPopProjectionMatrix();
- gpuPopMatrix();
+ GPU_matrix_pop_projection();
+ GPU_matrix_pop();
GPU_blend(false);
@@ -881,7 +881,7 @@ void ED_view3d_draw_depth_gpencil(
GPU_depth_test(true);
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ if (v3d->flag2 & V3D_SHOW_ANNOTATION) {
ED_gpencil_draw_view3d(NULL, scene, view_layer, depsgraph, v3d, ar, true);
}
@@ -1033,7 +1033,7 @@ bool ED_view3d_calc_render_border(const Scene *scene, Depsgraph *depsgraph, View
bool use_border;
/* test if there is a 3d view rendering */
- if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene))
+ if (v3d->shading.type != OB_RENDER || !view3d_main_region_do_render_draw(scene))
return false;
/* test if there is a border render */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 792a341fba4..468b33ea9a6 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -52,6 +52,7 @@
#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_font.h"
+#include "BKE_gpencil.h"
#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -77,7 +78,6 @@
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_mesh.h"
-#include "ED_gpencil.h"
#include "ED_view3d.h"
#include "ED_transform_snap_object_context.h"
@@ -2811,7 +2811,7 @@ static int viewselected_exec(bContext *C, wmOperator *op)
Depsgraph *depsgraph = CTX_data_depsgraph(C);
ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
bGPdata *gpd = CTX_data_gpencil_data(C);
- const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
+ const bool is_gp_edit = GPENCIL_ANY_MODE(gpd);
const bool is_face_map = ((is_gp_edit == false) && ar->gizmo_map &&
WM_gizmomap_is_any_selected(ar->gizmo_map));
Object *ob_eval = OBACT(view_layer_eval);
@@ -2850,9 +2850,7 @@ static int viewselected_exec(bContext *C, wmOperator *op)
{
/* we're only interested in selected points here... */
if ((gps->flag & GP_STROKE_SELECT) && (gps->flag & GP_STROKE_3DSPACE)) {
- if (ED_gpencil_stroke_minmax(gps, true, min, max)) {
- ok = true;
- }
+ ok |= BKE_gpencil_stroke_minmax(gps, true, min, max);
}
}
CTX_DATA_END;
@@ -4625,7 +4623,7 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
/* cursor position in vec, result in vec, mval in region coords */
/* note: cannot use event->mval here (called by object_add() */
-void ED_view3d_cursor3d_position(bContext *C, const int mval[2], bool use_depth, float cursor_co[3])
+void ED_view3d_cursor3d_position(bContext *C, const int mval[2], const bool use_depth, float cursor_co[3])
{
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -4873,7 +4871,7 @@ static int toggle_shading_exec(bContext *C, wmOperator *op)
int type = RNA_enum_get(op->ptr, "type");
if (type == OB_SOLID) {
- if (v3d->drawtype == OB_SOLID) {
+ if (v3d->shading.type == OB_SOLID) {
/* Toggle X-Ray if already in solid mode. */
if (ED_operator_posemode(C) || ED_operator_editmesh(C)) {
v3d->flag ^= V3D_ZBUF_SELECT;
@@ -4884,24 +4882,24 @@ static int toggle_shading_exec(bContext *C, wmOperator *op)
}
else {
/* Go to solid mode. */
- v3d->drawtype = OB_SOLID;
+ v3d->shading.type = OB_SOLID;
}
}
else if (type == OB_MATERIAL) {
- if (v3d->drawtype == OB_MATERIAL) {
- v3d->drawtype = OB_SOLID;
+ if (v3d->shading.type == OB_MATERIAL) {
+ v3d->shading.type = OB_SOLID;
}
else {
- v3d->drawtype = OB_MATERIAL;
+ v3d->shading.type = OB_MATERIAL;
}
}
else if (type == OB_RENDER) {
- if (v3d->drawtype == OB_RENDER) {
- v3d->drawtype = v3d->prev_drawtype;
+ if (v3d->shading.type == OB_RENDER) {
+ v3d->shading.type = v3d->shading.prev_type;
}
else {
- v3d->prev_drawtype = v3d->drawtype;
- v3d->drawtype = OB_RENDER;
+ v3d->shading.prev_type = v3d->shading.type;
+ v3d->shading.type = OB_RENDER;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index d1b9f95ca2a..3cf036e1ce1 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -263,14 +263,14 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar),
x2 = xoff + 0.55f * fly->width;
y2 = yoff + 0.55f * fly->height;
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ 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_VIEW_OVERLAY);
- immBegin(GWN_PRIM_LINES, 16);
+ immBegin(GPU_PRIM_LINES, 16);
/* bottom left */
immVertex2f(pos, x1, y1);
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_armature.c b/source/blender/editors/space_view3d/view3d_gizmo_armature.c
index c7b12529798..88a95e89bd8 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_armature.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_armature.c
@@ -80,14 +80,14 @@ struct BoneSplineWidgetGroup {
};
static void gizmo_bbone_offset_get(
- const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop,
+ const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
void *value_p)
{
- struct BoneSplineHandle *bh = mpr_prop->custom_func.user_data;
+ struct BoneSplineHandle *bh = gz_prop->custom_func.user_data;
bPoseChannel *pchan = bh->pchan;
float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 3);
+ BLI_assert(gz_prop->type->array_length == 3);
if (bh->index == 0) {
bh->co[1] = pchan->bone->ease1 / BBONE_SCALE_Y;
@@ -103,15 +103,15 @@ static void gizmo_bbone_offset_get(
}
static void gizmo_bbone_offset_set(
- const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop,
+ const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
const void *value_p)
{
- struct BoneSplineHandle *bh = mpr_prop->custom_func.user_data;
+ struct BoneSplineHandle *bh = gz_prop->custom_func.user_data;
bPoseChannel *pchan = bh->pchan;
const float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 3);
+ BLI_assert(gz_prop->type->array_length == 3);
copy_v3_v3(bh->co, value);
if (bh->index == 0) {
@@ -127,7 +127,7 @@ static void gizmo_bbone_offset_set(
}
-static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
if (ob != NULL) {
@@ -136,7 +136,7 @@ static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType
if (arm->act_bone && arm->act_bone->segments > 1) {
View3D *v3d = CTX_wm_view3d(C);
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) ||
- (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
+ (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
{
/* pass */
}
@@ -150,59 +150,59 @@ static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType
}
-static void WIDGETGROUP_armature_spline_setup(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_armature_spline_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
bPoseChannel *pchan = BKE_pose_channel_active(ob);
- const wmGizmoType *wt_grab = WM_gizmotype_find("GIZMO_WT_grab_3d", true);
+ const wmGizmoType *gzt_grab = WM_gizmotype_find("GIZMO_GT_grab_3d", true);
struct BoneSplineWidgetGroup *bspline_group = MEM_callocN(sizeof(struct BoneSplineWidgetGroup), __func__);
- mgroup->customdata = bspline_group;
+ gzgroup->customdata = bspline_group;
/* Handles */
for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
- wmGizmo *mpr;
- mpr = bspline_group->handles[i].gizmo = WM_gizmo_new_ptr(wt_grab, mgroup, NULL);
- RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_RING_2D);
- RNA_enum_set(mpr->ptr, "draw_options",
+ wmGizmo *gz;
+ gz = bspline_group->handles[i].gizmo = WM_gizmo_new_ptr(gzt_grab, gzgroup, NULL);
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_RING_2D);
+ RNA_enum_set(gz->ptr, "draw_options",
ED_GIZMO_GRAB_DRAW_FLAG_FILL | ED_GIZMO_GRAB_DRAW_FLAG_ALIGN_VIEW);
- WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_VALUE, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_VALUE, true);
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
- mpr->scale_basis = 0.06f;
+ gz->scale_basis = 0.06f;
if (i == 0) {
- copy_v3_v3(mpr->matrix_basis[3], pchan->loc);
+ copy_v3_v3(gz->matrix_basis[3], pchan->loc);
}
}
}
-static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
- if (!mgroup->customdata)
+ if (!gzgroup->customdata)
return;
- struct BoneSplineWidgetGroup *bspline_group = mgroup->customdata;
+ struct BoneSplineWidgetGroup *bspline_group = gzgroup->customdata;
bPoseChannel *pchan = BKE_pose_channel_active(ob);
/* Handles */
for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
- wmGizmo *mpr = bspline_group->handles[i].gizmo;
+ wmGizmo *gz = bspline_group->handles[i].gizmo;
bspline_group->handles[i].pchan = pchan;
bspline_group->handles[i].index = i;
float mat[4][4];
mul_m4_m4m4(mat, ob->obmat, (i == 0) ? pchan->disp_mat : pchan->disp_tail_mat);
- copy_m4_m4(mpr->matrix_space, mat);
+ copy_m4_m4(gz->matrix_space, mat);
/* need to set property here for undo. TODO would prefer to do this in _init */
WM_gizmo_target_property_def_func(
- mpr, "offset",
+ gz, "offset",
&(const struct wmGizmoPropertyFnParams) {
.value_get_fn = gizmo_bbone_offset_get,
.value_set_fn = gizmo_bbone_offset_set,
@@ -212,17 +212,17 @@ static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmGizmoGroup
}
}
-void VIEW3D_WGT_armature_spline(wmGizmoGroupType *wgt)
+void VIEW3D_GGT_armature_spline(wmGizmoGroupType *gzgt)
{
- wgt->name = "Armature Spline Widgets";
- wgt->idname = "VIEW3D_WGT_armature_spline";
+ gzgt->name = "Armature Spline Widgets";
+ gzgt->idname = "VIEW3D_GGT_armature_spline";
- wgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT |
+ gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT |
WM_GIZMOGROUPTYPE_3D);
- wgt->poll = WIDGETGROUP_armature_spline_poll;
- wgt->setup = WIDGETGROUP_armature_spline_setup;
- wgt->refresh = WIDGETGROUP_armature_spline_refresh;
+ gzgt->poll = WIDGETGROUP_armature_spline_poll;
+ gzgt->setup = WIDGETGROUP_armature_spline_setup;
+ gzgt->refresh = WIDGETGROUP_armature_spline_refresh;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_camera.c b/source/blender/editors/space_view3d/view3d_gizmo_camera.c
index b011e6e2e21..87b11f5d7a3 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_camera.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_camera.c
@@ -61,11 +61,11 @@ struct CameraWidgetGroup {
wmGizmo *ortho_scale;
};
-static bool WIDGETGROUP_camera_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_camera_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
View3D *v3d = CTX_wm_view3d(C);
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) ||
- (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
+ (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
{
return false;
}
@@ -81,57 +81,57 @@ static bool WIDGETGROUP_camera_poll(const bContext *C, wmGizmoGroupType *UNUSED(
return false;
}
-static void WIDGETGROUP_camera_setup(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_camera_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
Object *ob = CTX_data_active_object(C);
float dir[3];
- const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_3d", true);
+ const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
- struct CameraWidgetGroup *camgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__);
- mgroup->customdata = camgroup;
+ struct CameraWidgetGroup *cagzgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__);
+ gzgroup->customdata = cagzgroup;
negate_v3_v3(dir, ob->obmat[2]);
/* dof distance */
{
- wmGizmo *mpr;
- mpr = camgroup->dop_dist = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL);
- RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CROSS);
- WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_HOVER, true);
+ wmGizmo *gz;
+ gz = cagzgroup->dop_dist = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CROSS);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true);
- UI_GetThemeColor3fv(TH_GIZMO_A, mpr->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi);
+ UI_GetThemeColor3fv(TH_GIZMO_A, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
}
/* focal length
* - logic/calculations are similar to BKE_camera_view_frame_ex, better keep in sync */
{
- wmGizmo *mpr;
- mpr = camgroup->focal_len = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL);
- mpr->flag |= WM_GIZMO_DRAW_NO_SCALE;
- RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE);
- RNA_enum_set(mpr->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
-
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi);
-
- mpr = camgroup->ortho_scale = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL);
- mpr->flag |= WM_GIZMO_DRAW_NO_SCALE;
- RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE);
- RNA_enum_set(mpr->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
-
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi);
+ wmGizmo *gz;
+ gz = cagzgroup->focal_len = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ gz->flag |= WM_GIZMO_DRAW_NO_SCALE;
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE);
+ RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
+
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+
+ gz = cagzgroup->ortho_scale = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ gz->flag |= WM_GIZMO_DRAW_NO_SCALE;
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE);
+ RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
+
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
}
}
-static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- if (!mgroup->customdata)
+ if (!gzgroup->customdata)
return;
- struct CameraWidgetGroup *camgroup = mgroup->customdata;
+ struct CameraWidgetGroup *cagzgroup = gzgroup->customdata;
Object *ob = CTX_data_active_object(C);
Camera *ca = ob->data;
PointerRNA camera_ptr;
@@ -149,16 +149,16 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *mgroup)
negate_v3_v3(dir, ob->obmat[2]);
if (ca->flag & CAM_SHOWLIMITS) {
- WM_gizmo_set_matrix_location(camgroup->dop_dist, ob->obmat[3]);
- WM_gizmo_set_matrix_rotation_from_yz_axis(camgroup->dop_dist, ob->obmat[1], dir);
- WM_gizmo_set_scale(camgroup->dop_dist, ca->drawsize);
- WM_gizmo_set_flag(camgroup->dop_dist, WM_GIZMO_HIDDEN, false);
+ WM_gizmo_set_matrix_location(cagzgroup->dop_dist, ob->obmat[3]);
+ WM_gizmo_set_matrix_rotation_from_yz_axis(cagzgroup->dop_dist, ob->obmat[1], dir);
+ WM_gizmo_set_scale(cagzgroup->dop_dist, ca->drawsize);
+ WM_gizmo_set_flag(cagzgroup->dop_dist, WM_GIZMO_HIDDEN, false);
/* need to set property here for undo. TODO would prefer to do this in _init */
- WM_gizmo_target_property_def_rna(camgroup->dop_dist, "offset", &camera_ptr, "dof_distance", -1);
+ WM_gizmo_target_property_def_rna(cagzgroup->dop_dist, "offset", &camera_ptr, "dof_distance", -1);
}
else {
- WM_gizmo_set_flag(camgroup->dop_dist, WM_GIZMO_HIDDEN, true);
+ WM_gizmo_set_flag(cagzgroup->dop_dist, WM_GIZMO_HIDDEN, true);
}
/* TODO - make focal length/ortho ob_scale_inv widget optional */
@@ -167,14 +167,14 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *mgroup)
const float aspy = (float)scene->r.ysch * scene->r.yasp;
const bool is_ortho = (ca->type == CAM_ORTHO);
const int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, aspx, aspy);
- wmGizmo *widget = is_ortho ? camgroup->ortho_scale : camgroup->focal_len;
+ wmGizmo *widget = is_ortho ? cagzgroup->ortho_scale : cagzgroup->focal_len;
float scale_matrix;
if (true) {
float offset[3];
float aspect[2];
WM_gizmo_set_flag(widget, WM_GIZMO_HIDDEN, false);
- WM_gizmo_set_flag(is_ortho ? camgroup->focal_len : camgroup->ortho_scale, WM_GIZMO_HIDDEN, true);
+ WM_gizmo_set_flag(is_ortho ? cagzgroup->focal_len : cagzgroup->ortho_scale, WM_GIZMO_HIDDEN, true);
/* account for lens shifting */
@@ -208,9 +208,9 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *mgroup)
{
const char *propname = is_ortho ? "ortho_scale" : "lens";
PropertyRNA *prop = RNA_struct_find_property(&camera_ptr, propname);
- const wmGizmoPropertyType *mpr_prop_type = WM_gizmotype_target_property_find(widget->type, "offset");
+ const wmGizmoPropertyType *gz_prop_type = WM_gizmotype_target_property_find(widget->type, "offset");
- WM_gizmo_target_property_clear_rna_ptr(widget, mpr_prop_type);
+ WM_gizmo_target_property_clear_rna_ptr(widget, gz_prop_type);
float min, max, range;
float step, precision;
@@ -226,21 +226,21 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *mgroup)
/* Half sensor, intentionally use sensor from camera and not calculated above. */
(0.5f * ((ca->sensor_fit == CAMERA_SENSOR_FIT_HOR) ? ca->sensor_x : ca->sensor_x))));
- WM_gizmo_target_property_def_rna_ptr(widget, mpr_prop_type, &camera_ptr, prop, -1);
+ WM_gizmo_target_property_def_rna_ptr(widget, gz_prop_type, &camera_ptr, prop, -1);
}
}
static void WIDGETGROUP_camera_message_subscribe(
- const bContext *C, wmGizmoGroup *mgroup, struct wmMsgBus *mbus)
+ const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
{
ARegion *ar = CTX_wm_region(C);
Object *ob = CTX_data_active_object(C);
Camera *ca = ob->data;
- wmMsgSubscribeValue msg_sub_value_mpr_tag_refresh = {
+ wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
.owner = ar,
- .user_data = mgroup->parent_mmap,
+ .user_data = gzgroup->parent_gzmap,
.notify = WM_gizmo_do_msg_notify_tag_refresh,
};
@@ -270,32 +270,32 @@ static void WIDGETGROUP_camera_message_subscribe(
RNA_id_pointer_create(&ca->id, &idptr);
for (int i = 0; i < ARRAY_SIZE(props); i++) {
- WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_mpr_tag_refresh, __func__);
+ WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
}
}
/* Subscribe to render settings */
{
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_x, &msg_sub_value_mpr_tag_refresh);
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_y, &msg_sub_value_mpr_tag_refresh);
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_x, &msg_sub_value_mpr_tag_refresh);
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_y, &msg_sub_value_mpr_tag_refresh);
+ WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_x, &msg_sub_value_gz_tag_refresh);
+ WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_y, &msg_sub_value_gz_tag_refresh);
+ WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_x, &msg_sub_value_gz_tag_refresh);
+ WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_y, &msg_sub_value_gz_tag_refresh);
}
}
-void VIEW3D_WGT_camera(wmGizmoGroupType *wgt)
+void VIEW3D_GGT_camera(wmGizmoGroupType *gzgt)
{
- wgt->name = "Camera Widgets";
- wgt->idname = "VIEW3D_WGT_camera";
+ gzgt->name = "Camera Widgets";
+ gzgt->idname = "VIEW3D_GGT_camera";
- wgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT |
+ gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT |
WM_GIZMOGROUPTYPE_3D |
WM_GIZMOGROUPTYPE_DEPTH_3D);
- wgt->poll = WIDGETGROUP_camera_poll;
- wgt->setup = WIDGETGROUP_camera_setup;
- wgt->refresh = WIDGETGROUP_camera_refresh;
- wgt->message_subscribe = WIDGETGROUP_camera_message_subscribe;
+ gzgt->poll = WIDGETGROUP_camera_poll;
+ gzgt->setup = WIDGETGROUP_camera_setup;
+ gzgt->refresh = WIDGETGROUP_camera_refresh;
+ gzgt->message_subscribe = WIDGETGROUP_camera_message_subscribe;
}
/** \} */
@@ -316,12 +316,12 @@ struct CameraViewWidgetGroup {
/* scale callbacks */
static void gizmo_render_border_prop_matrix_get(
- const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop,
+ const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
void *value_p)
{
float (*matrix)[4] = value_p;
- BLI_assert(mpr_prop->type->array_length == 16);
- struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data;
+ BLI_assert(gz_prop->type->array_length == 16);
+ struct CameraViewWidgetGroup *viewgroup = gz_prop->custom_func.user_data;
const rctf *border = viewgroup->state.edit_border;
unit_m4(matrix);
@@ -332,20 +332,20 @@ static void gizmo_render_border_prop_matrix_get(
}
static void gizmo_render_border_prop_matrix_set(
- const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop,
+ const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
const void *value_p)
{
const float (*matrix)[4] = value_p;
- struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data;
+ struct CameraViewWidgetGroup *viewgroup = gz_prop->custom_func.user_data;
rctf *border = viewgroup->state.edit_border;
- BLI_assert(mpr_prop->type->array_length == 16);
+ BLI_assert(gz_prop->type->array_length == 16);
BLI_rctf_resize(border, len_v3(matrix[0]), len_v3(matrix[1]));
BLI_rctf_recenter(border, matrix[3][0], matrix[3][1]);
BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, border, border);
}
-static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
Scene *scene = CTX_data_scene(C);
@@ -361,7 +361,7 @@ static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmGizmoGroupType *UN
View3D *v3d = CTX_wm_view3d(C);
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) ||
- (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
+ (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
{
return false;
}
@@ -382,11 +382,11 @@ static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmGizmoGroupType *UN
return false;
}
-static void WIDGETGROUP_camera_view_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_camera_view_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
struct CameraViewWidgetGroup *viewgroup = MEM_mallocN(sizeof(struct CameraViewWidgetGroup), __func__);
- viewgroup->border = WM_gizmo_new("GIZMO_WT_cage_2d", mgroup, NULL);
+ viewgroup->border = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
RNA_enum_set(viewgroup->border->ptr, "transform",
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
@@ -394,12 +394,12 @@ static void WIDGETGROUP_camera_view_setup(const bContext *UNUSED(C), wmGizmoGrou
RNA_enum_set(viewgroup->border->ptr, "draw_style", ED_GIZMO_CAGE2D_STYLE_BOX);
- mgroup->customdata = viewgroup;
+ gzgroup->customdata = viewgroup;
}
-static void WIDGETGROUP_camera_view_draw_prepare(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_camera_view_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct CameraViewWidgetGroup *viewgroup = mgroup->customdata;
+ struct CameraViewWidgetGroup *viewgroup = gzgroup->customdata;
ARegion *ar = CTX_wm_region(C);
struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
@@ -413,17 +413,17 @@ static void WIDGETGROUP_camera_view_draw_prepare(const bContext *C, wmGizmoGroup
viewgroup->state.view_border = (rctf){.xmin = 0, .ymin = 0, .xmax = ar->winx, .ymax = ar->winy};
}
- wmGizmo *mpr = viewgroup->border;
- unit_m4(mpr->matrix_space);
- mul_v3_fl(mpr->matrix_space[0], BLI_rctf_size_x(&viewgroup->state.view_border));
- mul_v3_fl(mpr->matrix_space[1], BLI_rctf_size_y(&viewgroup->state.view_border));
- mpr->matrix_space[3][0] = viewgroup->state.view_border.xmin;
- mpr->matrix_space[3][1] = viewgroup->state.view_border.ymin;
+ wmGizmo *gz = viewgroup->border;
+ unit_m4(gz->matrix_space);
+ mul_v3_fl(gz->matrix_space[0], BLI_rctf_size_x(&viewgroup->state.view_border));
+ mul_v3_fl(gz->matrix_space[1], BLI_rctf_size_y(&viewgroup->state.view_border));
+ gz->matrix_space[3][0] = viewgroup->state.view_border.xmin;
+ gz->matrix_space[3][1] = viewgroup->state.view_border.ymin;
}
-static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct CameraViewWidgetGroup *viewgroup = mgroup->customdata;
+ struct CameraViewWidgetGroup *viewgroup = gzgroup->customdata;
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
@@ -431,8 +431,8 @@ static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *mgr
Scene *scene = CTX_data_scene(C);
{
- wmGizmo *mpr = viewgroup->border;
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false);
+ wmGizmo *gz = viewgroup->border;
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
RNA_enum_set(viewgroup->border->ptr, "transform",
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
@@ -445,7 +445,7 @@ static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *mgr
}
WM_gizmo_target_property_def_func(
- mpr, "matrix",
+ gz, "matrix",
&(const struct wmGizmoPropertyFnParams) {
.value_get_fn = gizmo_render_border_prop_matrix_get,
.value_set_fn = gizmo_render_border_prop_matrix_set,
@@ -456,18 +456,18 @@ static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *mgr
}
-void VIEW3D_WGT_camera_view(wmGizmoGroupType *wgt)
+void VIEW3D_GGT_camera_view(wmGizmoGroupType *gzgt)
{
- wgt->name = "Camera View Widgets";
- wgt->idname = "VIEW3D_WGT_camera_view";
+ gzgt->name = "Camera View Widgets";
+ gzgt->idname = "VIEW3D_GGT_camera_view";
- wgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT |
+ gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT |
WM_GIZMOGROUPTYPE_SCALE);
- wgt->poll = WIDGETGROUP_camera_view_poll;
- wgt->setup = WIDGETGROUP_camera_view_setup;
- wgt->draw_prepare = WIDGETGROUP_camera_view_draw_prepare;
- wgt->refresh = WIDGETGROUP_camera_view_refresh;
+ gzgt->poll = WIDGETGROUP_camera_view_poll;
+ gzgt->setup = WIDGETGROUP_camera_view_setup;
+ gzgt->draw_prepare = WIDGETGROUP_camera_view_draw_prepare;
+ gzgt->refresh = WIDGETGROUP_camera_view_refresh;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_empty.c b/source/blender/editors/space_view3d/view3d_gizmo_empty.c
index 3b51af5ca15..2913ba245e7 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_empty.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_empty.c
@@ -63,20 +63,20 @@ struct EmptyImageWidgetGroup {
/* translate callbacks */
static void gizmo_empty_image_prop_matrix_get(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
void *value_p)
{
float (*matrix)[4] = value_p;
- BLI_assert(mpr_prop->type->array_length == 16);
- struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
- const Object *ob = imgroup->state.ob;
+ BLI_assert(gz_prop->type->array_length == 16);
+ struct EmptyImageWidgetGroup *igzgroup = gz_prop->custom_func.user_data;
+ const Object *ob = igzgroup->state.ob;
unit_m4(matrix);
matrix[0][0] = ob->empty_drawsize;
matrix[1][1] = ob->empty_drawsize;
float dims[2] = {0.0f, 0.0f};
- RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ RNA_float_get_array(gz->ptr, "dimensions", dims);
dims[0] *= ob->empty_drawsize;
dims[1] *= ob->empty_drawsize;
@@ -85,18 +85,18 @@ static void gizmo_empty_image_prop_matrix_get(
}
static void gizmo_empty_image_prop_matrix_set(
- const wmGizmo *mpr, wmGizmoProperty *mpr_prop,
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
const void *value_p)
{
const float (*matrix)[4] = value_p;
- BLI_assert(mpr_prop->type->array_length == 16);
- struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
- Object *ob = imgroup->state.ob;
+ BLI_assert(gz_prop->type->array_length == 16);
+ struct EmptyImageWidgetGroup *igzgroup = gz_prop->custom_func.user_data;
+ Object *ob = igzgroup->state.ob;
ob->empty_drawsize = matrix[0][0];
float dims[2];
- RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ RNA_float_get_array(gz->ptr, "dimensions", dims);
dims[0] *= ob->empty_drawsize;
dims[1] *= ob->empty_drawsize;
@@ -104,12 +104,12 @@ static void gizmo_empty_image_prop_matrix_set(
ob->ima_ofs[1] = (matrix[3][1] - (0.5f * dims[1])) / dims[1];
}
-static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
View3D *v3d = CTX_wm_view3d(C);
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) ||
- (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
+ (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
{
return false;
}
@@ -122,36 +122,36 @@ static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmGizmoGroupType *UN
return false;
}
-static void WIDGETGROUP_empty_image_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_empty_image_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- struct EmptyImageWidgetGroup *imgroup = MEM_mallocN(sizeof(struct EmptyImageWidgetGroup), __func__);
- imgroup->gizmo = WM_gizmo_new("GIZMO_WT_cage_2d", mgroup, NULL);
- wmGizmo *mpr = imgroup->gizmo;
- RNA_enum_set(mpr->ptr, "transform",
+ struct EmptyImageWidgetGroup *igzgroup = MEM_mallocN(sizeof(struct EmptyImageWidgetGroup), __func__);
+ igzgroup->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
+ wmGizmo *gz = igzgroup->gizmo;
+ RNA_enum_set(gz->ptr, "transform",
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
- mgroup->customdata = imgroup;
+ gzgroup->customdata = igzgroup;
- WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_HOVER, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true);
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
}
-static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct EmptyImageWidgetGroup *imgroup = mgroup->customdata;
+ struct EmptyImageWidgetGroup *igzgroup = gzgroup->customdata;
Object *ob = CTX_data_active_object(C);
- wmGizmo *mpr = imgroup->gizmo;
+ wmGizmo *gz = igzgroup->gizmo;
- copy_m4_m4(mpr->matrix_basis, ob->obmat);
+ copy_m4_m4(gz->matrix_basis, ob->obmat);
- RNA_enum_set(mpr->ptr, "transform",
+ RNA_enum_set(gz->ptr, "transform",
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE |
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE |
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM);
- imgroup->state.ob = ob;
+ igzgroup->state.ob = ob;
/* Use dimensions for aspect. */
if (ob->data != NULL) {
@@ -169,36 +169,36 @@ static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmGizmoGroup *mgr
}
const float dims_max = max_ff(size[0], size[1]);
- imgroup->state.dims[0] = size[0] / dims_max;
- imgroup->state.dims[1] = size[1] / dims_max;
+ igzgroup->state.dims[0] = size[0] / dims_max;
+ igzgroup->state.dims[1] = size[1] / dims_max;
}
else {
- copy_v2_fl(imgroup->state.dims, 1.0f);
+ copy_v2_fl(igzgroup->state.dims, 1.0f);
}
- RNA_float_set_array(mpr->ptr, "dimensions", imgroup->state.dims);
+ RNA_float_set_array(gz->ptr, "dimensions", igzgroup->state.dims);
WM_gizmo_target_property_def_func(
- mpr, "matrix",
+ gz, "matrix",
&(const struct wmGizmoPropertyFnParams) {
.value_get_fn = gizmo_empty_image_prop_matrix_get,
.value_set_fn = gizmo_empty_image_prop_matrix_set,
.range_get_fn = NULL,
- .user_data = imgroup,
+ .user_data = igzgroup,
});
}
-void VIEW3D_WGT_empty_image(wmGizmoGroupType *wgt)
+void VIEW3D_GGT_empty_image(wmGizmoGroupType *gzgt)
{
- wgt->name = "Area Light Widgets";
- wgt->idname = "VIEW3D_WGT_empty_image";
+ gzgt->name = "Area Light Widgets";
+ gzgt->idname = "VIEW3D_GGT_empty_image";
- wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
WM_GIZMOGROUPTYPE_3D |
WM_GIZMOGROUPTYPE_DEPTH_3D);
- wgt->poll = WIDGETGROUP_empty_image_poll;
- wgt->setup = WIDGETGROUP_empty_image_setup;
- wgt->refresh = WIDGETGROUP_empty_image_refresh;
+ gzgt->poll = WIDGETGROUP_empty_image_poll;
+ gzgt->setup = WIDGETGROUP_empty_image_setup;
+ gzgt->refresh = WIDGETGROUP_empty_image_refresh;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
index d4605bb0c7d..e2a8d2802e7 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
@@ -52,12 +52,12 @@
/** \name Force Field Gizmos
* \{ */
-static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
View3D *v3d = CTX_wm_view3d(C);
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) ||
- (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
+ (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
{
return false;
}
@@ -67,26 +67,26 @@ static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmGizmoGroupType *UNU
return (ob && ob->pd && ob->pd->forcefield);
}
-static void WIDGETGROUP_forcefield_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_forcefield_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
/* only wind effector for now */
wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
- mgroup->customdata = wwrapper;
+ gzgroup->customdata = wwrapper;
- wwrapper->gizmo = WM_gizmo_new("GIZMO_WT_arrow_3d", mgroup, NULL);
- wmGizmo *mpr = wwrapper->gizmo;
- RNA_enum_set(mpr->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
- ED_gizmo_arrow3d_set_ui_range(mpr, -200.0f, 200.0f);
- ED_gizmo_arrow3d_set_range_fac(mpr, 6.0f);
+ wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_arrow_3d", gzgroup, NULL);
+ wmGizmo *gz = wwrapper->gizmo;
+ RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
+ ED_gizmo_arrow3d_set_ui_range(gz, -200.0f, 200.0f);
+ ED_gizmo_arrow3d_set_range_fac(gz, 6.0f);
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
}
-static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- wmGizmoWrapper *wwrapper = mgroup->customdata;
- wmGizmo *mpr = wwrapper->gizmo;
+ wmGizmoWrapper *wwrapper = gzgroup->customdata;
+ wmGizmo *gz = wwrapper->gizmo;
Object *ob = CTX_data_active_object(C);
PartDeflect *pd = ob->pd;
@@ -96,30 +96,30 @@ static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmGizmoGroup *mgro
PointerRNA field_ptr;
RNA_pointer_create(&ob->id, &RNA_FieldSettings, pd, &field_ptr);
- WM_gizmo_set_matrix_location(mpr, ob->obmat[3]);
- WM_gizmo_set_matrix_rotation_from_z_axis(mpr, ob->obmat[2]);
- WM_gizmo_set_matrix_offset_location(mpr, ofs);
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false);
- WM_gizmo_target_property_def_rna(mpr, "offset", &field_ptr, "strength", -1);
+ WM_gizmo_set_matrix_location(gz, ob->obmat[3]);
+ WM_gizmo_set_matrix_rotation_from_z_axis(gz, ob->obmat[2]);
+ WM_gizmo_set_matrix_offset_location(gz, ofs);
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
+ WM_gizmo_target_property_def_rna(gz, "offset", &field_ptr, "strength", -1);
}
else {
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
}
}
-void VIEW3D_WGT_force_field(wmGizmoGroupType *wgt)
+void VIEW3D_GGT_force_field(wmGizmoGroupType *gzgt)
{
- wgt->name = "Force Field Widgets";
- wgt->idname = "VIEW3D_WGT_force_field";
+ gzgt->name = "Force Field Widgets";
+ gzgt->idname = "VIEW3D_GGT_force_field";
- wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
WM_GIZMOGROUPTYPE_3D |
WM_GIZMOGROUPTYPE_SCALE |
WM_GIZMOGROUPTYPE_DEPTH_3D);
- wgt->poll = WIDGETGROUP_forcefield_poll;
- wgt->setup = WIDGETGROUP_forcefield_setup;
- wgt->refresh = WIDGETGROUP_forcefield_refresh;
+ gzgt->poll = WIDGETGROUP_forcefield_poll;
+ gzgt->setup = WIDGETGROUP_forcefield_setup;
+ gzgt->refresh = WIDGETGROUP_forcefield_refresh;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_lamp.c b/source/blender/editors/space_view3d/view3d_gizmo_lamp.c
index a872cc96172..057c085b69d 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_lamp.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_lamp.c
@@ -52,11 +52,11 @@
/** \name Spot Lamp Gizmos
* \{ */
-static bool WIDGETGROUP_lamp_spot_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_lamp_spot_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
View3D *v3d = CTX_wm_view3d(C);
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) ||
- (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
+ (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
{
return false;
}
@@ -70,53 +70,53 @@ static bool WIDGETGROUP_lamp_spot_poll(const bContext *C, wmGizmoGroupType *UNUS
return false;
}
-static void WIDGETGROUP_lamp_spot_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_lamp_spot_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
- wwrapper->gizmo = WM_gizmo_new("GIZMO_WT_arrow_3d", mgroup, NULL);
- wmGizmo *mpr = wwrapper->gizmo;
- RNA_enum_set(mpr->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_INVERTED);
+ wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_arrow_3d", gzgroup, NULL);
+ wmGizmo *gz = wwrapper->gizmo;
+ RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_INVERTED);
- mgroup->customdata = wwrapper;
+ gzgroup->customdata = wwrapper;
- ED_gizmo_arrow3d_set_range_fac(mpr, 4.0f);
+ ED_gizmo_arrow3d_set_range_fac(gz, 4.0f);
- UI_GetThemeColor3fv(TH_GIZMO_SECONDARY, mpr->color);
+ UI_GetThemeColor3fv(TH_GIZMO_SECONDARY, gz->color);
}
-static void WIDGETGROUP_lamp_spot_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_lamp_spot_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- wmGizmoWrapper *wwrapper = mgroup->customdata;
- wmGizmo *mpr = wwrapper->gizmo;
+ wmGizmoWrapper *wwrapper = gzgroup->customdata;
+ wmGizmo *gz = wwrapper->gizmo;
Object *ob = CTX_data_active_object(C);
Lamp *la = ob->data;
float dir[3];
negate_v3_v3(dir, ob->obmat[2]);
- WM_gizmo_set_matrix_rotation_from_z_axis(mpr, dir);
- WM_gizmo_set_matrix_location(mpr, ob->obmat[3]);
+ WM_gizmo_set_matrix_rotation_from_z_axis(gz, dir);
+ WM_gizmo_set_matrix_location(gz, ob->obmat[3]);
/* need to set property here for undo. TODO would prefer to do this in _init */
PointerRNA lamp_ptr;
const char *propname = "spot_size";
RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr);
- WM_gizmo_target_property_def_rna(mpr, "offset", &lamp_ptr, propname, -1);
+ WM_gizmo_target_property_def_rna(gz, "offset", &lamp_ptr, propname, -1);
}
-void VIEW3D_WGT_lamp_spot(wmGizmoGroupType *wgt)
+void VIEW3D_GGT_lamp_spot(wmGizmoGroupType *gzgt)
{
- wgt->name = "Spot Light Widgets";
- wgt->idname = "VIEW3D_WGT_lamp_spot";
+ gzgt->name = "Spot Light Widgets";
+ gzgt->idname = "VIEW3D_GGT_lamp_spot";
- wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
WM_GIZMOGROUPTYPE_3D |
WM_GIZMOGROUPTYPE_DEPTH_3D);
- wgt->poll = WIDGETGROUP_lamp_spot_poll;
- wgt->setup = WIDGETGROUP_lamp_spot_setup;
- wgt->refresh = WIDGETGROUP_lamp_spot_refresh;
+ gzgt->poll = WIDGETGROUP_lamp_spot_poll;
+ gzgt->setup = WIDGETGROUP_lamp_spot_setup;
+ gzgt->refresh = WIDGETGROUP_lamp_spot_refresh;
}
/** \} */
@@ -128,24 +128,24 @@ void VIEW3D_WGT_lamp_spot(wmGizmoGroupType *wgt)
/* scale callbacks */
static void gizmo_area_lamp_prop_matrix_get(
- const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop,
+ const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
void *value_p)
{
- BLI_assert(mpr_prop->type->array_length == 16);
+ BLI_assert(gz_prop->type->array_length == 16);
float (*matrix)[4] = value_p;
- const Lamp *la = mpr_prop->custom_func.user_data;
+ const Lamp *la = gz_prop->custom_func.user_data;
matrix[0][0] = la->area_size;
matrix[1][1] = ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE) ? la->area_sizey : la->area_size;
}
static void gizmo_area_lamp_prop_matrix_set(
- const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop,
+ const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
const void *value_p)
{
const float (*matrix)[4] = value_p;
- BLI_assert(mpr_prop->type->array_length == 16);
- Lamp *la = mpr_prop->custom_func.user_data;
+ BLI_assert(gz_prop->type->array_length == 16);
+ Lamp *la = gz_prop->custom_func.user_data;
if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) {
la->area_size = len_v3(matrix[0]);
@@ -156,7 +156,7 @@ static void gizmo_area_lamp_prop_matrix_set(
}
}
-static bool WIDGETGROUP_lamp_area_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_lamp_area_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
View3D *v3d = CTX_wm_view3d(C);
if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
@@ -171,40 +171,40 @@ static bool WIDGETGROUP_lamp_area_poll(const bContext *C, wmGizmoGroupType *UNUS
return false;
}
-static void WIDGETGROUP_lamp_area_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_lamp_area_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
- wwrapper->gizmo = WM_gizmo_new("GIZMO_WT_cage_2d", mgroup, NULL);
- wmGizmo *mpr = wwrapper->gizmo;
- RNA_enum_set(mpr->ptr, "transform",
+ wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
+ wmGizmo *gz = wwrapper->gizmo;
+ RNA_enum_set(gz->ptr, "transform",
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
- mgroup->customdata = wwrapper;
+ gzgroup->customdata = wwrapper;
- WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_HOVER, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true);
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
}
-static void WIDGETGROUP_lamp_area_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_lamp_area_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- wmGizmoWrapper *wwrapper = mgroup->customdata;
+ wmGizmoWrapper *wwrapper = gzgroup->customdata;
Object *ob = CTX_data_active_object(C);
Lamp *la = ob->data;
- wmGizmo *mpr = wwrapper->gizmo;
+ wmGizmo *gz = wwrapper->gizmo;
- copy_m4_m4(mpr->matrix_basis, ob->obmat);
+ copy_m4_m4(gz->matrix_basis, ob->obmat);
int flag = ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE;
if (ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_DISK)) {
flag |= ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM;
}
- RNA_enum_set(mpr->ptr, "transform", flag);
+ RNA_enum_set(gz->ptr, "transform", flag);
/* need to set property here for undo. TODO would prefer to do this in _init */
WM_gizmo_target_property_def_func(
- mpr, "matrix",
+ gz, "matrix",
&(const struct wmGizmoPropertyFnParams) {
.value_get_fn = gizmo_area_lamp_prop_matrix_get,
.value_set_fn = gizmo_area_lamp_prop_matrix_set,
@@ -213,18 +213,18 @@ static void WIDGETGROUP_lamp_area_refresh(const bContext *C, wmGizmoGroup *mgrou
});
}
-void VIEW3D_WGT_lamp_area(wmGizmoGroupType *wgt)
+void VIEW3D_GGT_lamp_area(wmGizmoGroupType *gzgt)
{
- wgt->name = "Area Light Widgets";
- wgt->idname = "VIEW3D_WGT_lamp_area";
+ gzgt->name = "Area Light Widgets";
+ gzgt->idname = "VIEW3D_GGT_lamp_area";
- wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
WM_GIZMOGROUPTYPE_3D |
WM_GIZMOGROUPTYPE_DEPTH_3D);
- wgt->poll = WIDGETGROUP_lamp_area_poll;
- wgt->setup = WIDGETGROUP_lamp_area_setup;
- wgt->refresh = WIDGETGROUP_lamp_area_refresh;
+ gzgt->poll = WIDGETGROUP_lamp_area_poll;
+ gzgt->setup = WIDGETGROUP_lamp_area_setup;
+ gzgt->refresh = WIDGETGROUP_lamp_area_refresh;
}
/** \} */
@@ -235,7 +235,7 @@ void VIEW3D_WGT_lamp_area(wmGizmoGroupType *wgt)
/** \name Lamp Target Gizmo
* \{ */
-static bool WIDGETGROUP_lamp_target_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_lamp_target_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
View3D *v3d = CTX_wm_view3d(C);
if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
@@ -258,50 +258,50 @@ static bool WIDGETGROUP_lamp_target_poll(const bContext *C, wmGizmoGroupType *UN
return false;
}
-static void WIDGETGROUP_lamp_target_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_lamp_target_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
- wwrapper->gizmo = WM_gizmo_new("GIZMO_WT_grab_3d", mgroup, NULL);
- wmGizmo *mpr = wwrapper->gizmo;
+ wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_grab_3d", gzgroup, NULL);
+ wmGizmo *gz = wwrapper->gizmo;
- mgroup->customdata = wwrapper;
+ gzgroup->customdata = wwrapper;
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
- mpr->scale_basis = 0.06f;
+ gz->scale_basis = 0.06f;
wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_transform_axis_target", true);
- RNA_enum_set(mpr->ptr, "draw_options",
+ RNA_enum_set(gz->ptr, "draw_options",
ED_GIZMO_GRAB_DRAW_FLAG_FILL | ED_GIZMO_GRAB_DRAW_FLAG_ALIGN_VIEW);
- WM_gizmo_operator_set(mpr, 0, ot, NULL);
+ WM_gizmo_operator_set(gz, 0, ot, NULL);
}
-static void WIDGETGROUP_lamp_target_draw_prepare(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_lamp_target_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- wmGizmoWrapper *wwrapper = mgroup->customdata;
+ wmGizmoWrapper *wwrapper = gzgroup->customdata;
Object *ob = CTX_data_active_object(C);
- wmGizmo *mpr = wwrapper->gizmo;
+ wmGizmo *gz = wwrapper->gizmo;
- copy_m4_m4(mpr->matrix_basis, ob->obmat);
- unit_m4(mpr->matrix_offset);
- mpr->matrix_offset[3][2] = -2.4f / mpr->scale_basis;
- WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_OFFSET_SCALE, true);
+ copy_m4_m4(gz->matrix_basis, ob->obmat);
+ unit_m4(gz->matrix_offset);
+ gz->matrix_offset[3][2] = -2.4f / gz->scale_basis;
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_OFFSET_SCALE, true);
}
-void VIEW3D_WGT_lamp_target(wmGizmoGroupType *wgt)
+void VIEW3D_GGT_lamp_target(wmGizmoGroupType *gzgt)
{
- wgt->name = "Target Light Widgets";
- wgt->idname = "VIEW3D_WGT_lamp_target";
+ gzgt->name = "Target Light Widgets";
+ gzgt->idname = "VIEW3D_GGT_lamp_target";
- wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
WM_GIZMOGROUPTYPE_3D);
- wgt->poll = WIDGETGROUP_lamp_target_poll;
- wgt->setup = WIDGETGROUP_lamp_target_setup;
- wgt->draw_prepare = WIDGETGROUP_lamp_target_draw_prepare;
+ gzgt->poll = WIDGETGROUP_lamp_target_poll;
+ gzgt->setup = WIDGETGROUP_lamp_target_setup;
+ gzgt->draw_prepare = WIDGETGROUP_lamp_target_draw_prepare;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
index f4a8bad7e30..5778f85a99c 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
@@ -131,31 +131,31 @@ struct NavigateGizmoInfo {
#define SHAPE_VARS(shape_id) shape = shape_id, .shape_size = ARRAY_SIZE(shape_id)
-struct NavigateGizmoInfo g_navigate_params[MPR_TOTAL] = {
+static struct NavigateGizmoInfo g_navigate_params[MPR_TOTAL] = {
{
.opname = "VIEW3D_OT_move",
- .gizmo = "GIZMO_WT_button_2d",
+ .gizmo = "GIZMO_GT_button_2d",
.SHAPE_VARS(shape_pan),
}, {
.opname = "VIEW3D_OT_rotate",
- .gizmo = "VIEW3D_WT_navigate_rotate",
+ .gizmo = "VIEW3D_GT_navigate_rotate",
.shape = NULL,
.shape_size = 0,
}, {
.opname = "VIEW3D_OT_zoom",
- .gizmo = "GIZMO_WT_button_2d",
+ .gizmo = "GIZMO_GT_button_2d",
.SHAPE_VARS(shape_zoom),
}, {
.opname = "VIEW3D_OT_view_persportho",
- .gizmo = "GIZMO_WT_button_2d",
+ .gizmo = "GIZMO_GT_button_2d",
.SHAPE_VARS(shape_persp),
}, {
.opname = "VIEW3D_OT_view_persportho",
- .gizmo = "GIZMO_WT_button_2d",
+ .gizmo = "GIZMO_GT_button_2d",
.SHAPE_VARS(shape_ortho),
}, {
.opname = "VIEW3D_OT_view_camera",
- .gizmo = "GIZMO_WT_button_2d",
+ .gizmo = "GIZMO_GT_button_2d",
.SHAPE_VARS(shape_camera),
},
};
@@ -163,7 +163,7 @@ struct NavigateGizmoInfo g_navigate_params[MPR_TOTAL] = {
#undef SHAPE_VARS
struct NavigateWidgetGroup {
- wmGizmo *mpr_array[MPR_TOTAL];
+ wmGizmo *gz_array[MPR_TOTAL];
/* Store the view state to check for changes. */
struct {
rcti rect_visible;
@@ -176,12 +176,12 @@ struct NavigateWidgetGroup {
int region_size[2];
};
-static bool WIDGETGROUP_navigate_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_navigate_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
View3D *v3d = CTX_wm_view3d(C);
if (((U.uiflag & USER_SHOW_GIZMO_AXIS) == 0) ||
(v3d->flag2 & V3D_RENDER_OVERRIDE) ||
- (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE)))
+ (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE)))
{
return false;
}
@@ -189,7 +189,7 @@ static bool WIDGETGROUP_navigate_poll(const bContext *C, wmGizmoGroupType *UNUSE
}
-static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
struct NavigateWidgetGroup *navgroup = MEM_callocN(sizeof(struct NavigateWidgetGroup), __func__);
@@ -201,53 +201,53 @@ static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup *
for (int i = 0; i < MPR_TOTAL; i++) {
const struct NavigateGizmoInfo *info = &g_navigate_params[i];
- navgroup->mpr_array[i] = WM_gizmo_new(info->gizmo, mgroup, NULL);
- wmGizmo *mpr = navgroup->mpr_array[i];
- mpr->flag |= WM_GIZMO_GRAB_CURSOR | WM_GIZMO_DRAW_MODAL;
- mpr->color[3] = 0.2f;
- mpr->color_hi[3] = 0.4f;
+ navgroup->gz_array[i] = WM_gizmo_new(info->gizmo, gzgroup, NULL);
+ wmGizmo *gz = navgroup->gz_array[i];
+ gz->flag |= WM_GIZMO_GRAB_CURSOR | WM_GIZMO_DRAW_MODAL;
+ gz->color[3] = 0.2f;
+ gz->color_hi[3] = 0.4f;
/* may be overwritten later */
- mpr->scale_basis = (GIZMO_SIZE * GIZMO_MINI_FAC) / 2;
+ gz->scale_basis = (GIZMO_SIZE * GIZMO_MINI_FAC) / 2;
if (info->shape != NULL) {
- PropertyRNA *prop = RNA_struct_find_property(mpr->ptr, "shape");
+ PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "shape");
RNA_property_string_set_bytes(
- mpr->ptr, prop,
+ gz->ptr, prop,
(const char *)info->shape, info->shape_size);
- RNA_enum_set(mpr->ptr, "draw_options", ED_GIZMO_BUTTON_SHOW_OUTLINE);
+ RNA_enum_set(gz->ptr, "draw_options", ED_GIZMO_BUTTON_SHOW_OUTLINE);
}
wmOperatorType *ot = WM_operatortype_find(info->opname, true);
- WM_gizmo_operator_set(mpr, 0, ot, NULL);
+ WM_gizmo_operator_set(gz, 0, ot, NULL);
}
{
- wmGizmo *mpr = navgroup->mpr_array[MPR_CAMERA];
- WM_gizmo_operator_set(mpr, 0, ot_view_camera, NULL);
+ wmGizmo *gz = navgroup->gz_array[MPR_CAMERA];
+ WM_gizmo_operator_set(gz, 0, ot_view_camera, NULL);
}
/* Click only buttons (not modal). */
{
- int mpr_ids[] = {MPR_PERSP, MPR_ORTHO, MPR_CAMERA};
- for (int i = 0; i < ARRAY_SIZE(mpr_ids); i++) {
- wmGizmo *mpr = navgroup->mpr_array[mpr_ids[i]];
- RNA_boolean_set(mpr->ptr, "show_drag", false);
+ int gz_ids[] = {MPR_PERSP, MPR_ORTHO, MPR_CAMERA};
+ for (int i = 0; i < ARRAY_SIZE(gz_ids); i++) {
+ wmGizmo *gz = navgroup->gz_array[gz_ids[i]];
+ RNA_boolean_set(gz->ptr, "show_drag", false);
}
}
/* Modal operators, don't use initial mouse location since we're clicking on a button. */
{
- int mpr_ids[] = {MPR_MOVE, MPR_ROTATE, MPR_ZOOM};
- for (int i = 0; i < ARRAY_SIZE(mpr_ids); i++) {
- wmGizmo *mpr = navgroup->mpr_array[mpr_ids[i]];
- wmGizmoOpElem *mpop = WM_gizmo_operator_get(mpr, 0);
+ int gz_ids[] = {MPR_MOVE, MPR_ROTATE, MPR_ZOOM};
+ for (int i = 0; i < ARRAY_SIZE(gz_ids); i++) {
+ wmGizmo *gz = navgroup->gz_array[gz_ids[i]];
+ wmGizmoOpElem *mpop = WM_gizmo_operator_get(gz, 0);
RNA_boolean_set(&mpop->ptr, "use_mouse_init", false);
}
}
{
- wmGizmo *mpr = navgroup->mpr_array[MPR_ROTATE];
- mpr->scale_basis = GIZMO_SIZE / 2;
+ wmGizmo *gz = navgroup->gz_array[MPR_ROTATE];
+ gz->scale_basis = GIZMO_SIZE / 2;
char mapping[6] = {
RV3D_VIEW_LEFT,
RV3D_VIEW_RIGHT,
@@ -258,25 +258,25 @@ static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup *
};
for (int part_index = 0; part_index < 6; part_index += 1) {
- PointerRNA *ptr = WM_gizmo_operator_set(mpr, part_index + 1, ot_view_axis, NULL);
+ PointerRNA *ptr = WM_gizmo_operator_set(gz, part_index + 1, ot_view_axis, NULL);
RNA_enum_set(ptr, "type", mapping[part_index]);
}
/* When dragging an axis, use this instead. */
- mpr->drag_part = 0;
+ gz->drag_part = 0;
}
- mgroup->customdata = navgroup;
+ gzgroup->customdata = navgroup;
}
-static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct NavigateWidgetGroup *navgroup = mgroup->customdata;
+ struct NavigateWidgetGroup *navgroup = gzgroup->customdata;
ARegion *ar = CTX_wm_region(C);
const RegionView3D *rv3d = ar->regiondata;
for (int i = 0; i < 3; i++) {
- copy_v3_v3(navgroup->mpr_array[MPR_ROTATE]->matrix_offset[i], rv3d->viewmat[i]);
+ copy_v3_v3(navgroup->gz_array[MPR_ROTATE]->matrix_offset[i], rv3d->viewmat[i]);
}
rcti rect_visible;
@@ -312,60 +312,60 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *m
rect_visible.ymax - icon_offset_mini * 0.75f,
};
- wmGizmo *mpr;
+ wmGizmo *gz;
- for (uint i = 0; i < ARRAY_SIZE(navgroup->mpr_array); i++) {
- mpr = navgroup->mpr_array[i];
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true);
+ for (uint i = 0; i < ARRAY_SIZE(navgroup->gz_array); i++) {
+ gz = navgroup->gz_array[i];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
}
/* RV3D_LOCKED or Camera: only show supported buttons. */
if (show_rotate) {
- mpr = navgroup->mpr_array[MPR_ROTATE];
- mpr->matrix_basis[3][0] = co_rotate[0];
- mpr->matrix_basis[3][1] = co_rotate[1];
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false);
+ gz = navgroup->gz_array[MPR_ROTATE];
+ gz->matrix_basis[3][0] = co_rotate[0];
+ gz->matrix_basis[3][1] = co_rotate[1];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
}
int icon_mini_slot = 0;
- mpr = navgroup->mpr_array[MPR_ZOOM];
- mpr->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
- mpr->matrix_basis[3][1] = co[1];
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false);
+ gz = navgroup->gz_array[MPR_ZOOM];
+ gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
+ gz->matrix_basis[3][1] = co[1];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
- mpr = navgroup->mpr_array[MPR_MOVE];
- mpr->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
- mpr->matrix_basis[3][1] = co[1];
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false);
+ gz = navgroup->gz_array[MPR_MOVE];
+ gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
+ gz->matrix_basis[3][1] = co[1];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
- mpr = navgroup->mpr_array[MPR_CAMERA];
- mpr->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
- mpr->matrix_basis[3][1] = co[1];
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false);
+ gz = navgroup->gz_array[MPR_CAMERA];
+ gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
+ gz->matrix_basis[3][1] = co[1];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
if (navgroup->state.rv3d.is_camera == false) {
- mpr = navgroup->mpr_array[rv3d->is_persp ? MPR_PERSP : MPR_ORTHO];
- mpr->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
- mpr->matrix_basis[3][1] = co[1];
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false);
+ gz = navgroup->gz_array[rv3d->is_persp ? MPR_PERSP : MPR_ORTHO];
+ gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
+ gz->matrix_basis[3][1] = co[1];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
}
}
}
-void VIEW3D_WGT_navigate(wmGizmoGroupType *wgt)
+void VIEW3D_GGT_navigate(wmGizmoGroupType *gzgt)
{
- wgt->name = "View3D Navigate";
- wgt->idname = "VIEW3D_WGT_navigate";
+ gzgt->name = "View3D Navigate";
+ gzgt->idname = "VIEW3D_GGT_navigate";
- wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
WM_GIZMOGROUPTYPE_SCALE |
WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL);
- wgt->poll = WIDGETGROUP_navigate_poll;
- wgt->setup = WIDGETGROUP_navigate_setup;
- wgt->draw_prepare = WIDGETGROUP_navigate_draw_prepare;
+ gzgt->poll = WIDGETGROUP_navigate_poll;
+ gzgt->setup = WIDGETGROUP_navigate_setup;
+ gzgt->draw_prepare = WIDGETGROUP_navigate_draw_prepare;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
index 041fe343526..5a4f910955e 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
@@ -84,7 +84,7 @@ static void draw_xyz_wire(
switch (axis) {
case 0: /* x axis */
- line_type = GWN_PRIM_LINES;
+ line_type = GPU_PRIM_LINES;
/* bottom left to top right */
negate_v3_v3(v1, dx);
@@ -105,7 +105,7 @@ static void draw_xyz_wire(
break;
case 1: /* y axis */
- line_type = GWN_PRIM_LINES;
+ line_type = GPU_PRIM_LINES;
/* bottom left to top right */
mul_v3_fl(dx, 0.75f);
@@ -127,7 +127,7 @@ static void draw_xyz_wire(
break;
case 2: /* z axis */
- line_type = GWN_PRIM_LINE_STRIP;
+ line_type = GPU_PRIM_LINE_STRIP;
/* start at top left */
negate_v3_v3(v1, dx);
@@ -168,12 +168,12 @@ static void draw_xyz_wire(
immEnd();
}
-static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool UNUSED(select))
+static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool UNUSED(select))
{
- GPU_line_width(mpr->line_width);
+ GPU_line_width(gz->line_width);
- Gwn_VertFormat *format = immVertexFormat();
- const uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
struct {
@@ -182,12 +182,12 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool
char axis;
char is_pos;
} axis_order[6] = {
- {-mpr->matrix_offset[0][2], 0, 0, false},
- {+mpr->matrix_offset[0][2], 1, 0, true},
- {-mpr->matrix_offset[1][2], 2, 1, false},
- {+mpr->matrix_offset[1][2], 3, 1, true},
- {-mpr->matrix_offset[2][2], 4, 2, false},
- {+mpr->matrix_offset[2][2], 5, 2, true},
+ {-gz->matrix_offset[0][2], 0, 0, false},
+ {+gz->matrix_offset[0][2], 1, 0, true},
+ {-gz->matrix_offset[1][2], 2, 1, false},
+ {+gz->matrix_offset[1][2], 3, 1, true},
+ {-gz->matrix_offset[2][2], 4, 2, false},
+ {+gz->matrix_offset[2][2], 5, 2, true},
};
qsort(&axis_order, ARRAY_SIZE(axis_order), sizeof(axis_order[0]), BLI_sortutil_cmp_float);
@@ -195,14 +195,14 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool
static const float axis_highlight[4] = {1, 1, 1, 1};
static const float axis_black[4] = {0, 0, 0, 1};
static float axis_color[3][4];
- gpuPushMatrix();
- gpuMultMatrix(mpr->matrix_offset);
+ GPU_matrix_push();
+ GPU_matrix_mul(gz->matrix_offset);
bool draw_center_done = false;
int axis_align = -1;
for (int axis = 0; axis < 3; axis++) {
- if (len_squared_v2(mpr->matrix_offset[axis]) < 1e-6f) {
+ if (len_squared_v2(gz->matrix_offset[axis]) < 1e-6f) {
axis_align = axis;
break;
}
@@ -212,18 +212,18 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool
const int index = axis_order[axis_index].index;
const int axis = axis_order[axis_index].axis;
const bool is_pos = axis_order[axis_index].is_pos;
- const bool is_highlight = index + 1 == mpr->highlight_part;
+ const bool is_highlight = index + 1 == gz->highlight_part;
/* Draw slightly before, so axis aligned arrows draw ontop. */
if ((draw_center_done == false) && (axis_order[axis_index].depth > -0.01f)) {
/* Circle defining active area (revert back to 2D space). */
{
- gpuPopMatrix();
+ GPU_matrix_pop();
immUniformColor4fv(color);
imm_draw_circle_fill_3d(pos_id, 0, 0, 1.0f, DIAL_RESOLUTION);
- gpuPushMatrix();
- gpuMultMatrix(mpr->matrix_offset);
+ GPU_matrix_push();
+ GPU_matrix_mul(gz->matrix_offset);
}
draw_center_done = true;
}
@@ -237,10 +237,13 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool
bool ok = true;
/* skip view align axis */
- if ((axis_align == axis) && (mpr->matrix_offset[axis][2] > 0.0f) == is_pos) {
+ if ((axis_align == axis) && (gz->matrix_offset[axis][2] > 0.0f) == is_pos) {
ok = false;
}
if (ok) {
+ /* Check aligned, since the front axis won't display in this case,
+ * and we want to make sure all 3 axes have a character at all times. */
+ const bool show_axis_char = (is_pos || (axis == axis_align));
const float v[3] = {0, 0, 3 * (is_pos ? 1 : -1)};
const float v_final[3] = {
v[index_x] * scale_axis,
@@ -257,7 +260,7 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool
float v_start[3];
GPU_line_width(2.0f);
immUniformColor4fv(color_current);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
if (axis_align == -1) {
zero_v3(v_start);
}
@@ -276,75 +279,75 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool
/* Axis Ball. */
{
- gpuPushMatrix();
- gpuTranslate3fv(v_final);
- gpuScaleUniform(is_pos ? 0.22f : 0.18f);
-
- Gwn_Batch *sphere = GPU_batch_preset_sphere(0);
- GWN_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
- GWN_batch_uniform_4fv(sphere, "color", is_pos ? color_current : color_current_fade);
- GWN_batch_draw(sphere);
- gpuPopMatrix();
+ GPU_matrix_push();
+ GPU_matrix_translate_3fv(v_final);
+ GPU_matrix_scale_1f(show_axis_char ? 0.22f : 0.18f);
+
+ GPUBatch *sphere = GPU_batch_preset_sphere(0);
+ GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
+ GPU_batch_uniform_4fv(sphere, "color", is_pos ? color_current : color_current_fade);
+ GPU_batch_draw(sphere);
+ GPU_matrix_pop();
}
/* Axis XYZ Character. */
- if (is_pos) {
+ if (show_axis_char) {
GPU_line_width(1.0f);
float m3[3][3];
- copy_m3_m4(m3, mpr->matrix_offset);
+ copy_m3_m4(m3, gz->matrix_offset);
immUniformColor4fv(is_highlight ? axis_black : axis_highlight);
draw_xyz_wire(pos_id, m3, v_final, 1.0, axis);
}
}
}
- gpuPopMatrix();
+ GPU_matrix_pop();
immUnbindProgram();
}
static void axis3d_draw_intern(
- const bContext *UNUSED(C), wmGizmo *mpr,
+ const bContext *UNUSED(C), wmGizmo *gz,
const bool select, const bool highlight)
{
- const float *color = highlight ? mpr->color_hi : mpr->color;
+ const float *color = highlight ? gz->color_hi : gz->color;
float matrix_final[4][4];
float matrix_unit[4][4];
unit_m4(matrix_unit);
WM_gizmo_calc_matrix_final_params(
- mpr,
+ gz,
&((struct WM_GizmoMatrixParams) {
.matrix_offset = matrix_unit,
}), matrix_final);
- gpuPushMatrix();
- gpuMultMatrix(matrix_final);
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix_final);
GPU_blend(true);
- axis_geom_draw(mpr, color, select);
+ axis_geom_draw(gz, color, select);
GPU_blend(false);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
-static void gizmo_axis_draw(const bContext *C, wmGizmo *mpr)
+static void gizmo_axis_draw(const bContext *C, wmGizmo *gz)
{
- const bool is_modal = mpr->state & WM_GIZMO_STATE_MODAL;
- const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
+ const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL;
+ const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
(void)is_modal;
GPU_blend(true);
- axis3d_draw_intern(C, mpr, false, is_highlight);
+ axis3d_draw_intern(C, gz, false, is_highlight);
GPU_blend(false);
}
static int gizmo_axis_test_select(
- bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event)
+ bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
{
- float point_local[2] = {UNPACK2(event->mval)};
- sub_v2_v2(point_local, mpr->matrix_basis[3]);
- mul_v2_fl(point_local, 1.0f / (mpr->scale_basis * UI_DPI_FAC));
+ float point_local[2] = {UNPACK2(mval)};
+ sub_v2_v2(point_local, gz->matrix_basis[3]);
+ mul_v2_fl(point_local, 1.0f / (gz->scale_basis * UI_DPI_FAC));
const float len_sq = len_squared_v2(point_local);
if (len_sq > 1.0) {
@@ -358,14 +361,14 @@ static int gizmo_axis_test_select(
for (int i = 0; i < 3; i++) {
for (int is_pos = 0; is_pos < 2; is_pos++) {
float co[2] = {
- mpr->matrix_offset[i][0] * (is_pos ? 1 : -1),
- mpr->matrix_offset[i][1] * (is_pos ? 1 : -1),
+ gz->matrix_offset[i][0] * (is_pos ? 1 : -1),
+ gz->matrix_offset[i][1] * (is_pos ? 1 : -1),
};
bool ok = true;
/* Check if we're viewing on an axis, there is no point to clicking on the current axis so show the reverse. */
- if (len_squared_v2(co) < 1e-6f && (mpr->matrix_offset[i][2] > 0.0f) == is_pos) {
+ if (len_squared_v2(co) < 1e-6f && (gz->matrix_offset[i][2] > 0.0f) == is_pos) {
ok = false;
}
@@ -384,7 +387,7 @@ static int gizmo_axis_test_select(
return part_best;
}
- /* The 'mpr->scale_final' is already applied when projecting. */
+ /* The 'gz->scale_final' is already applied when projecting. */
if (len_sq < 1.0f) {
return 0;
}
@@ -392,23 +395,23 @@ static int gizmo_axis_test_select(
return -1;
}
-static int gizmo_axis_cursor_get(wmGizmo *mpr)
+static int gizmo_axis_cursor_get(wmGizmo *gz)
{
- if (mpr->highlight_part > 0) {
+ if (gz->highlight_part > 0) {
return CURSOR_EDIT;
}
return BC_NSEW_SCROLLCURSOR;
}
-void VIEW3D_WT_navigate_rotate(wmGizmoType *wt)
+void VIEW3D_GT_navigate_rotate(wmGizmoType *gzt)
{
/* identifiers */
- wt->idname = "VIEW3D_WT_navigate_rotate";
+ gzt->idname = "VIEW3D_GT_navigate_rotate";
/* api callbacks */
- wt->draw = gizmo_axis_draw;
- wt->test_select = gizmo_axis_test_select;
- wt->cursor_get = gizmo_axis_cursor_get;
+ gzt->draw = gizmo_axis_draw;
+ gzt->test_select = gizmo_axis_test_select;
+ gzt->cursor_get = gizmo_axis_cursor_get;
- wt->struct_size = sizeof(wmGizmo);
+ gzt->struct_size = sizeof(wmGizmo);
}
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
index ac6a984bea5..5853fa6e3b3 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
@@ -36,13 +36,16 @@
#include "BKE_object.h"
#include "BKE_unit.h"
+#include "BKE_material.h"
+#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_view3d_types.h"
#include "BIF_gl.h"
+#include "ED_gpencil.h"
#include "ED_screen.h"
#include "ED_transform_snap_object_context.h"
#include "ED_view3d.h"
@@ -68,7 +71,7 @@
#include "BLF_api.h"
-static const char *view3d_wgt_ruler_id = "VIEW3D_WGT_ruler";
+static const char *view3d_gzgt_ruler_id = "VIEW3D_GGT_ruler";
#define MVAL_MAX_PX_DIST 12.0f
@@ -123,7 +126,7 @@ typedef struct RulerInfo {
/* Ruler Item (two or three points) */
typedef struct RulerItem {
- wmGizmo mpr;
+ wmGizmo gz;
/* worldspace coords, middle being optional */
float co[3][3];
@@ -143,18 +146,18 @@ typedef struct RulerInteraction {
/** \name Internal Ruler Utilities
* \{ */
-static RulerItem *ruler_item_add(wmGizmoGroup *mgroup)
+static RulerItem *ruler_item_add(wmGizmoGroup *gzgroup)
{
/* could pass this as an arg */
- const wmGizmoType *wt_ruler = WM_gizmotype_find("VIEW3D_WT_ruler_item", true);
- RulerItem *ruler_item = (RulerItem *)WM_gizmo_new_ptr(wt_ruler, mgroup, NULL);
- WM_gizmo_set_flag(&ruler_item->mpr, WM_GIZMO_DRAW_MODAL, true);
+ const wmGizmoType *gzt_ruler = WM_gizmotype_find("VIEW3D_GT_ruler_item", true);
+ RulerItem *ruler_item = (RulerItem *)WM_gizmo_new_ptr(gzt_ruler, gzgroup, NULL);
+ WM_gizmo_set_flag(&ruler_item->gz, WM_GIZMO_DRAW_MODAL, true);
return ruler_item;
}
-static void ruler_item_remove(bContext *C, wmGizmoGroup *mgroup, RulerItem *ruler_item)
+static void ruler_item_remove(bContext *C, wmGizmoGroup *gzgroup, RulerItem *ruler_item)
{
- WM_gizmo_unlink(&mgroup->gizmos, mgroup->parent_mmap, &ruler_item->mpr, C);
+ WM_gizmo_unlink(&gzgroup->gizmos, gzgroup->parent_gzmap, &ruler_item->gz, C);
}
static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit,
@@ -192,10 +195,10 @@ static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit,
}
static bool view3d_ruler_pick(
- wmGizmoGroup *mgroup, RulerItem *ruler_item, const float mval[2],
+ wmGizmoGroup *gzgroup, RulerItem *ruler_item, const float mval[2],
int *r_co_index)
{
- RulerInfo *ruler_info = mgroup->customdata;
+ RulerInfo *ruler_info = gzgroup->customdata;
ARegion *ar = ruler_info->ar;
bool found = false;
@@ -304,7 +307,7 @@ static bool view3d_ruler_item_mousemove(
RulerInfo *ruler_info, RulerItem *ruler_item, const int mval[2],
const bool do_thickness, const bool do_snap)
{
- RulerInteraction *inter = ruler_item->mpr.interaction_data;
+ RulerInteraction *inter = ruler_item->gz.interaction_data;
const float eps_bias = 0.0002f;
float dist_px = MVAL_MAX_PX_DIST * U.pixelsize; /* snap dist */
@@ -380,46 +383,37 @@ static bool view3d_ruler_item_mousemove(
* \{ */
#define RULER_ID "RulerData3D"
-static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *mgroup)
+static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup)
{
- // RulerInfo *ruler_info = mgroup->customdata;
+ // RulerInfo *ruler_info = gzgroup->customdata;
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+
+ bGPdata *gpd;
bGPDlayer *gpl;
bGPDframe *gpf;
bGPDstroke *gps;
- bGPDpalette *palette;
- bGPDpalettecolor *palcolor;
RulerItem *ruler_item;
const char *ruler_name = RULER_ID;
bool changed = false;
if (scene->gpd == NULL) {
- scene->gpd = BKE_gpencil_data_addnew(bmain, "GPencil");
+ scene->gpd = BKE_gpencil_data_addnew(bmain, "Annotations");
}
+ gpd = scene->gpd;
- gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
+ gpl = BLI_findstring(&gpd->layers, ruler_name, offsetof(bGPDlayer, info));
if (gpl == NULL) {
- gpl = BKE_gpencil_layer_addnew(scene->gpd, ruler_name, false);
+ gpl = BKE_gpencil_layer_addnew(gpd, ruler_name, false);
+ copy_v4_v4(gpl->color, U.gpencil_new_layer_col);
gpl->thickness = 1;
gpl->flag |= GP_LAYER_HIDE;
}
- /* try to get active palette or create a new one */
- palette = BKE_gpencil_palette_getactive(scene->gpd);
- if (palette == NULL) {
- palette = BKE_gpencil_palette_addnew(scene->gpd, DATA_("GP_Palette"), true);
- }
- /* try to get color with the ruler name or create a new one */
- palcolor = BKE_gpencil_palettecolor_getbyname(palette, (char *)ruler_name);
- if (palcolor == NULL) {
- palcolor = BKE_gpencil_palettecolor_addnew(palette, (char *)ruler_name, true);
- }
-
gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true);
BKE_gpencil_free_strokes(gpf);
- for (ruler_item = mgroup->gizmos.first; ruler_item; ruler_item = (RulerItem *)ruler_item->mpr.next) {
+ for (ruler_item = gzgroup->gizmos.first; ruler_item; ruler_item = (RulerItem *)ruler_item->gz.next) {
bGPDspoint *pt;
int j;
@@ -428,6 +422,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *mgroup)
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
gps->totpoints = 3;
pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights");
for (j = 0; j < 3; j++) {
copy_v3_v3(&pt->x, ruler_item->co[j]);
pt->pressure = 1.0f;
@@ -438,6 +433,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *mgroup)
else {
gps->totpoints = 2;
pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights");
for (j = 0; j < 3; j += 2) {
copy_v3_v3(&pt->x, ruler_item->co[j]);
pt->pressure = 1.0f;
@@ -447,9 +443,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *mgroup)
}
gps->flag = GP_STROKE_3DSPACE;
gps->thickness = 3;
- /* assign color to stroke */
- BLI_strncpy(gps->colorname, palcolor->info, sizeof(gps->colorname));
- gps->palcolor = palcolor;
+
BLI_addtail(&gpf->strokes, gps);
changed = true;
}
@@ -457,7 +451,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *mgroup)
return changed;
}
-static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *mgroup)
+static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *gzgroup)
{
Scene *scene = CTX_data_scene(C);
bool changed = false;
@@ -476,7 +470,7 @@ static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *mgroup)
int j;
RulerItem *ruler_item = NULL;
if (gps->totpoints == 3) {
- ruler_item = ruler_item_add(mgroup);
+ ruler_item = ruler_item_add(gzgroup);
for (j = 0; j < 3; j++) {
copy_v3_v3(ruler_item->co[j], &pt->x);
pt++;
@@ -485,7 +479,7 @@ static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *mgroup)
changed = true;
}
else if (gps->totpoints == 2) {
- ruler_item = ruler_item_add(mgroup);
+ ruler_item = ruler_item_add(gzgroup);
for (j = 0; j < 3; j += 2) {
copy_v3_v3(ruler_item->co[j], &pt->x);
pt++;
@@ -506,12 +500,12 @@ static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *mgroup)
/** \name Ruler Item Gizmo Type
* \{ */
-static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr)
+static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
{
Scene *scene = CTX_data_scene(C);
UnitSettings *unit = &scene->unit;
- RulerInfo *ruler_info = mpr->parent_mgroup->customdata;
- RulerItem *ruler_item = (RulerItem *)mpr;
+ RulerInfo *ruler_info = gz->parent_gzgroup->customdata;
+ RulerItem *ruler_item = (RulerItem *)gz;
ARegion *ar = ruler_info->ar;
RegionView3D *rv3d = ar->regiondata;
const float cap_size = 4.0f;
@@ -536,7 +530,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr)
UI_GetThemeColor3ubv(TH_TEXT, color_text);
UI_GetThemeColor3ubv(TH_WIRE, color_wire);
- const bool is_act = (mpr->flag & WM_GIZMO_DRAW_HOVER);
+ const bool is_act = (gz->flag & WM_GIZMO_DRAW_HOVER);
float dir_ruler[2];
float co_ss[3][2];
int j;
@@ -548,7 +542,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr)
GPU_blend(true);
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -562,7 +556,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr)
immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
immUniform1f("dash_width", 6.0f);
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2fv(shdr_pos, co_ss[0]);
immVertex2fv(shdr_pos, co_ss[1]);
@@ -604,7 +598,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr)
immUniformColor3ubv(color_wire);
- immBegin(GWN_PRIM_LINE_STRIP, arc_steps + 1);
+ immBegin(GPU_PRIM_LINE_STRIP, arc_steps + 1);
for (j = 0; j <= arc_steps; j++) {
madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale);
@@ -637,7 +631,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr)
immUniformColor3ubv(color_wire);
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
immVertex2fv(shdr_pos, cap);
@@ -702,7 +696,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr)
immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
immUniform1f("dash_width", 6.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2fv(shdr_pos, co_ss[0]);
immVertex2fv(shdr_pos, co_ss[2]);
@@ -726,7 +720,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr)
immUniformColor3ubv(color_wire);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
immVertex2fv(shdr_pos, cap);
@@ -785,15 +779,15 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr)
/* draw snap */
if ((ruler_info->snap_flag & RULER_SNAP_OK) &&
(ruler_info->state == RULER_STATE_DRAG) &&
- (ruler_item->mpr.interaction_data != NULL))
+ (ruler_item->gz.interaction_data != NULL))
{
- RulerInteraction *inter = ruler_item->mpr.interaction_data;
+ RulerInteraction *inter = ruler_item->gz.interaction_data;
/* size from drawSnapping */
const float size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
float co_ss_snap[3];
ED_view3d_project_float_global(ar, ruler_item->co[inter->co_index], co_ss_snap, V3D_PROJ_TEST_NOP);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(color_act);
@@ -805,14 +799,14 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr)
}
static int gizmo_ruler_test_select(
- bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event)
+ bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
{
- RulerItem *ruler_item_pick = (RulerItem *)mpr;
- float mval_fl[2] = {UNPACK2(event->mval)};
+ RulerItem *ruler_item_pick = (RulerItem *)gz;
+ float mval_fl[2] = {UNPACK2(mval)};
int co_index;
/* select and drag */
- if (view3d_ruler_pick(mpr->parent_mgroup, ruler_item_pick, mval_fl, &co_index)) {
+ if (view3d_ruler_pick(gz->parent_gzgroup, ruler_item_pick, mval_fl, &co_index)) {
if (co_index == -1) {
if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
return PART_LINE;
@@ -826,14 +820,14 @@ static int gizmo_ruler_test_select(
}
static int gizmo_ruler_modal(
- bContext *C, wmGizmo *mpr, const wmEvent *event,
+ bContext *C, wmGizmo *gz, const wmEvent *event,
eWM_GizmoFlagTweak UNUSED(tweak_flag))
{
bool do_draw = false;
int exit_code = OPERATOR_RUNNING_MODAL;
- RulerInfo *ruler_info = mpr->parent_mgroup->customdata;
- RulerItem *ruler_item = (RulerItem *)mpr;
- RulerInteraction *inter = ruler_item->mpr.interaction_data;
+ RulerInfo *ruler_info = gz->parent_gzgroup->customdata;
+ RulerItem *ruler_item = (RulerItem *)gz;
+ RulerInteraction *inter = ruler_item->gz.interaction_data;
ARegion *ar = CTX_wm_region(C);
ruler_info->ar = ar;
@@ -860,20 +854,20 @@ static int gizmo_ruler_modal(
}
static int gizmo_ruler_invoke(
- bContext *C, wmGizmo *mpr, const wmEvent *event)
+ bContext *C, wmGizmo *gz, const wmEvent *event)
{
- wmGizmoGroup *mgroup = mpr->parent_mgroup;
- RulerInfo *ruler_info = mgroup->customdata;
- RulerItem *ruler_item_pick = (RulerItem *)mpr;
+ wmGizmoGroup *gzgroup = gz->parent_gzgroup;
+ RulerInfo *ruler_info = gzgroup->customdata;
+ RulerItem *ruler_item_pick = (RulerItem *)gz;
RulerInteraction *inter = MEM_callocN(sizeof(RulerInteraction), __func__);
- mpr->interaction_data = inter;
+ gz->interaction_data = inter;
ARegion *ar = ruler_info->ar;
const float mval_fl[2] = {UNPACK2(event->mval)};
/* select and drag */
- if (mpr->highlight_part == PART_LINE) {
+ if (gz->highlight_part == PART_LINE) {
if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
/* Add Center Point */
ruler_item_pick->flag |= RULERITEM_USE_ANGLE;
@@ -903,7 +897,7 @@ static int gizmo_ruler_invoke(
}
}
else {
- inter->co_index = mpr->highlight_part;
+ inter->co_index = gz->highlight_part;
ruler_state_set(C, ruler_info, RULER_STATE_DRAG);
/* store the initial depth */
@@ -913,15 +907,15 @@ static int gizmo_ruler_invoke(
return OPERATOR_RUNNING_MODAL;
}
-static void gizmo_ruler_exit(bContext *C, wmGizmo *mpr, const bool cancel)
+static void gizmo_ruler_exit(bContext *C, wmGizmo *gz, const bool cancel)
{
- wmGizmoGroup *mgroup = mpr->parent_mgroup;
- RulerInfo *ruler_info = mgroup->customdata;
+ wmGizmoGroup *gzgroup = gz->parent_gzgroup;
+ RulerInfo *ruler_info = gzgroup->customdata;
if (!cancel) {
if (ruler_info->state == RULER_STATE_DRAG) {
- RulerItem *ruler_item = (RulerItem *)mpr;
- RulerInteraction *inter = mpr->interaction_data;
+ RulerItem *ruler_item = (RulerItem *)gz;
+ RulerInteraction *inter = gz->interaction_data;
/* rubber-band angle removal */
if (!inter->inside_region) {
if ((inter->co_index == 1) && (ruler_item->flag & RULERITEM_USE_ANGLE)) {
@@ -930,9 +924,9 @@ static void gizmo_ruler_exit(bContext *C, wmGizmo *mpr, const bool cancel)
else {
/* Not ideal, since the ruler isn't a mode and we don't want to override delete key
* use dragging out of the view for removal. */
- ruler_item_remove(C, mgroup, ruler_item);
+ ruler_item_remove(C, gzgroup, ruler_item);
ruler_item = NULL;
- mpr = NULL;
+ gz = NULL;
inter = NULL;
}
}
@@ -942,38 +936,38 @@ static void gizmo_ruler_exit(bContext *C, wmGizmo *mpr, const bool cancel)
ruler_state_set(C, ruler_info, RULER_STATE_NORMAL);
}
/* We could convert only the current gizmo, for now just re-generate. */
- view3d_ruler_to_gpencil(C, mgroup);
+ view3d_ruler_to_gpencil(C, gzgroup);
}
- if (mpr) {
- MEM_SAFE_FREE(mpr->interaction_data);
+ if (gz) {
+ MEM_SAFE_FREE(gz->interaction_data);
}
ruler_state_set(C, ruler_info, RULER_STATE_NORMAL);
}
-static int gizmo_ruler_cursor_get(wmGizmo *mpr)
+static int gizmo_ruler_cursor_get(wmGizmo *gz)
{
- if (mpr->highlight_part == PART_LINE) {
+ if (gz->highlight_part == PART_LINE) {
return BC_CROSSCURSOR;
}
return BC_NSEW_SCROLLCURSOR;
}
-void VIEW3D_WT_ruler_item(wmGizmoType *wt)
+void VIEW3D_GT_ruler_item(wmGizmoType *gzt)
{
/* identifiers */
- wt->idname = "VIEW3D_WT_ruler_item";
+ gzt->idname = "VIEW3D_GT_ruler_item";
/* api callbacks */
- wt->draw = gizmo_ruler_draw;
- wt->test_select = gizmo_ruler_test_select;
- wt->modal = gizmo_ruler_modal;
- wt->invoke = gizmo_ruler_invoke;
- wt->exit = gizmo_ruler_exit;
- wt->cursor_get = gizmo_ruler_cursor_get;
-
- wt->struct_size = sizeof(RulerItem);
+ gzt->draw = gizmo_ruler_draw;
+ gzt->test_select = gizmo_ruler_test_select;
+ gzt->modal = gizmo_ruler_modal;
+ gzt->invoke = gizmo_ruler_invoke;
+ gzt->exit = gizmo_ruler_exit;
+ gzt->cursor_get = gizmo_ruler_cursor_get;
+
+ gzt->struct_size = sizeof(RulerItem);
}
/** \} */
@@ -982,23 +976,23 @@ void VIEW3D_WT_ruler_item(wmGizmoType *wt)
/** \name Ruler Gizmo Group
* \{ */
-static bool WIDGETGROUP_ruler_poll(const bContext *C, wmGizmoGroupType *wgt)
+static bool WIDGETGROUP_ruler_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C);
if ((tref_rt == NULL) ||
- !STREQ(wgt->idname, tref_rt->gizmo_group))
+ !STREQ(gzgt->idname, tref_rt->gizmo_group))
{
- WM_gizmo_group_type_unlink_delayed_ptr(wgt);
+ WM_gizmo_group_type_unlink_delayed_ptr(gzgt);
return false;
}
return true;
}
-static void WIDGETGROUP_ruler_setup(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_ruler_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
RulerInfo *ruler_info = MEM_callocN(sizeof(RulerInfo), __func__);
- if (view3d_ruler_from_gpencil(C, mgroup)) {
+ if (view3d_ruler_from_gpencil(C, gzgroup)) {
/* nop */
}
@@ -1009,21 +1003,21 @@ static void WIDGETGROUP_ruler_setup(const bContext *C, wmGizmoGroup *mgroup)
ruler_info->sa = sa;
ruler_info->ar = ar;
- mgroup->customdata = ruler_info;
+ gzgroup->customdata = ruler_info;
}
-void VIEW3D_WGT_ruler(wmGizmoGroupType *wgt)
+void VIEW3D_GGT_ruler(wmGizmoGroupType *gzgt)
{
- wgt->name = "Ruler Widgets";
- wgt->idname = view3d_wgt_ruler_id;
+ gzgt->name = "Ruler Widgets";
+ gzgt->idname = view3d_gzgt_ruler_id;
- wgt->flag |= WM_GIZMOGROUPTYPE_SCALE | WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL;
+ gzgt->flag |= WM_GIZMOGROUPTYPE_SCALE | WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL;
- wgt->mmap_params.spaceid = SPACE_VIEW3D;
- wgt->mmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- wgt->poll = WIDGETGROUP_ruler_poll;
- wgt->setup = WIDGETGROUP_ruler_setup;
+ gzgt->poll = WIDGETGROUP_ruler_poll;
+ gzgt->setup = WIDGETGROUP_ruler_setup;
}
/** \} */
@@ -1036,7 +1030,7 @@ static bool view3d_ruler_poll(bContext *C)
{
bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C);
if ((tref_rt == NULL) ||
- !STREQ(view3d_wgt_ruler_id, tref_rt->gizmo_group) ||
+ !STREQ(view3d_gzgt_ruler_id, tref_rt->gizmo_group) ||
CTX_wm_region_view3d(C) == NULL)
{
return false;
@@ -1050,22 +1044,22 @@ static int view3d_ruler_add_invoke(bContext *C, wmOperator *UNUSED(op), const wm
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = ar->regiondata;
- wmGizmoMap *mmap = ar->gizmo_map;
- wmGizmoGroup *mgroup = WM_gizmomap_group_find(mmap, view3d_wgt_ruler_id);
- const bool use_depth = (v3d->drawtype >= OB_SOLID);
+ wmGizmoMap *gzmap = ar->gizmo_map;
+ wmGizmoGroup *gzgroup = WM_gizmomap_group_find(gzmap, view3d_gzgt_ruler_id);
+ const bool use_depth = (v3d->shading.type >= OB_SOLID);
/* Create new line */
RulerItem *ruler_item;
- ruler_item = ruler_item_add(mgroup);
+ ruler_item = ruler_item_add(gzgroup);
/* This is a little weak, but there is no real good way to tweak directly. */
- WM_gizmo_highlight_set(mmap, &ruler_item->mpr);
+ WM_gizmo_highlight_set(gzmap, &ruler_item->gz);
if (WM_operator_name_call(
C, "GIZMOGROUP_OT_gizmo_tweak",
WM_OP_INVOKE_REGION_WIN, NULL) == OPERATOR_RUNNING_MODAL)
{
- RulerInfo *ruler_info = mgroup->customdata;
- RulerInteraction *inter = ruler_item->mpr.interaction_data;
+ RulerInfo *ruler_info = gzgroup->customdata;
+ RulerInteraction *inter = ruler_item->gz.interaction_data;
if (use_depth) {
/* snap the first point added, not essential but handy */
inter->co_index = 0;
@@ -1079,7 +1073,7 @@ static int view3d_ruler_add_invoke(bContext *C, wmOperator *UNUSED(op), const wm
}
copy_v3_v3(ruler_item->co[2], ruler_item->co[0]);
- ruler_item->mpr.highlight_part = inter->co_index = 2;
+ ruler_item->gz.highlight_part = inter->co_index = 2;
}
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index c9277235d50..83cabd2a60e 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -245,6 +245,7 @@ void VIEW3D_OT_toggle_matcap_flip(wmOperatorType *ot)
/* api callbacks */
ot->exec = toggle_matcap_flip;
+ ot->poll = ED_operator_view3d_active;
}
/** \} */
@@ -320,7 +321,9 @@ static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C)
else {
uiLayout *row = uiLayoutRow(layout, true);
uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ }
}
}
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 89dd254c130..855ee7bb9fc 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -39,7 +39,7 @@ struct ARegion;
struct ARegionType;
struct Base;
struct BoundBox;
-struct Gwn_Batch;
+struct GPUBatch;
struct Depsgraph;
struct Object;
struct SmokeDomainSettings;
@@ -254,21 +254,21 @@ ARegion *view3d_has_tools_region(ScrArea *sa);
extern const char *view3d_context_dir[]; /* doc access */
/* view3d_widgets.c */
-void VIEW3D_WGT_lamp_spot(struct wmGizmoGroupType *wgt);
-void VIEW3D_WGT_lamp_area(struct wmGizmoGroupType *wgt);
-void VIEW3D_WGT_lamp_target(struct wmGizmoGroupType *wgt);
-void VIEW3D_WGT_camera(struct wmGizmoGroupType *wgt);
-void VIEW3D_WGT_camera_view(struct wmGizmoGroupType *wgt);
-void VIEW3D_WGT_force_field(struct wmGizmoGroupType *wgt);
-void VIEW3D_WGT_empty_image(struct wmGizmoGroupType *wgt);
-void VIEW3D_WGT_armature_spline(struct wmGizmoGroupType *wgt);
-void VIEW3D_WGT_navigate(struct wmGizmoGroupType *wgt);
-
-void VIEW3D_WGT_ruler(struct wmGizmoGroupType *wgt);
-void VIEW3D_WT_ruler_item(struct wmGizmoType *wt);
+void VIEW3D_GGT_lamp_spot(struct wmGizmoGroupType *gzgt);
+void VIEW3D_GGT_lamp_area(struct wmGizmoGroupType *gzgt);
+void VIEW3D_GGT_lamp_target(struct wmGizmoGroupType *gzgt);
+void VIEW3D_GGT_camera(struct wmGizmoGroupType *gzgt);
+void VIEW3D_GGT_camera_view(struct wmGizmoGroupType *gzgt);
+void VIEW3D_GGT_force_field(struct wmGizmoGroupType *gzgt);
+void VIEW3D_GGT_empty_image(struct wmGizmoGroupType *gzgt);
+void VIEW3D_GGT_armature_spline(struct wmGizmoGroupType *gzgt);
+void VIEW3D_GGT_navigate(struct wmGizmoGroupType *gzgt);
+
+void VIEW3D_GGT_ruler(struct wmGizmoGroupType *gzgt);
+void VIEW3D_GT_ruler_item(struct wmGizmoType *gzt);
void VIEW3D_OT_ruler_add(struct wmOperatorType *ot);
-void VIEW3D_WT_navigate_rotate(struct wmGizmoType *wt);
+void VIEW3D_GT_navigate_rotate(struct wmGizmoType *gzt);
/* draw_volume.c */
void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index eae0cf8e459..74071e77901 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -380,7 +380,7 @@ void lattice_foreachScreenVert(
Object *obedit = vc->obedit;
Lattice *lt = obedit->data;
BPoint *bp = lt->editlatt->latt->def;
- DispList *dl = obedit->curve_cache ? BKE_displist_find(&obedit->curve_cache->disp, DL_VERTS) : NULL;
+ DispList *dl = obedit->runtime.curve_cache ? BKE_displist_find(&obedit->runtime.curve_cache->disp, DL_VERTS) : NULL;
const float *co = dl ? dl->verts : NULL;
int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 30b91c1a8ee..91e255aec82 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -677,7 +677,7 @@ void ED_view3d_project(const struct ARegion *ar, const float world[3], float reg
RegionView3D *rv3d = ar->regiondata;
int viewport[4] = {0, 0, ar->winx, ar->winy};
- gpuProject(world, rv3d->viewmat, rv3d->winmat, viewport, region);
+ GPU_matrix_project(world, rv3d->viewmat, rv3d->winmat, viewport, region);
}
bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony, float regionz, float world[3])
@@ -686,5 +686,5 @@ bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony,
int viewport[4] = {0, 0, ar->winx, ar->winy};
float region[3] = {regionx, regiony, regionz};
- return gpuUnProject(region, rv3d->viewmat, rv3d->winmat, viewport, world);
+ return GPU_matrix_unproject(region, rv3d->viewmat, rv3d->winmat, viewport, world);
}
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
index 4617b92c780..0475159712b 100644
--- a/source/blender/editors/space_view3d/view3d_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -26,9 +26,11 @@
/* defines VIEW3D_OT_ruler modal operator */
+#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_brush_types.h"
#include "MEM_guardedalloc.h"
@@ -40,6 +42,7 @@
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_main.h"
+#include "BKE_material.h"
#include "BKE_unit.h"
#include "BIF_gl.h"
@@ -51,6 +54,7 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "ED_gpencil.h"
#include "ED_screen.h"
#include "ED_view3d.h"
#include "ED_transform_snap_object_context.h"
@@ -300,37 +304,28 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+
bGPDlayer *gpl;
bGPDframe *gpf;
bGPDstroke *gps;
- bGPDpalette *palette;
- bGPDpalettecolor *palcolor;
RulerItem *ruler_item;
const char *ruler_name = RULER_ID;
bool changed = false;
+ /* FIXME: This needs to be reviewed. Should it keep being done like this? */
if (scene->gpd == NULL) {
- scene->gpd = BKE_gpencil_data_addnew(bmain, "GPencil");
+ scene->gpd = BKE_gpencil_data_addnew(bmain, "Annotations");
}
+ bGPdata *gpd = scene->gpd;
- gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
+ gpl = BLI_findstring(&gpd->layers, ruler_name, offsetof(bGPDlayer, info));
if (gpl == NULL) {
- gpl = BKE_gpencil_layer_addnew(scene->gpd, ruler_name, false);
+ gpl = BKE_gpencil_layer_addnew(gpd, ruler_name, false);
+ copy_v4_v4(gpl->color, U.gpencil_new_layer_col);
gpl->thickness = 1;
gpl->flag |= GP_LAYER_HIDE;
}
- /* try to get active palette or create a new one */
- palette = BKE_gpencil_palette_getactive(scene->gpd);
- if (palette == NULL) {
- palette = BKE_gpencil_palette_addnew(scene->gpd, DATA_("GP_Palette"), true);
- }
- /* try to get color with the ruler name or create a new one */
- palcolor = BKE_gpencil_palettecolor_getbyname(palette, (char *)ruler_name);
- if (palcolor == NULL) {
- palcolor = BKE_gpencil_palettecolor_addnew(palette, (char *)ruler_name, true);
- }
-
gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true);
BKE_gpencil_free_strokes(gpf);
@@ -343,6 +338,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info)
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
gps->totpoints = 3;
pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights");
for (j = 0; j < 3; j++) {
copy_v3_v3(&pt->x, ruler_item->co[j]);
pt->pressure = 1.0f;
@@ -353,6 +349,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info)
else {
gps->totpoints = 2;
pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights");
for (j = 0; j < 3; j += 2) {
copy_v3_v3(&pt->x, ruler_item->co[j]);
pt->pressure = 1.0f;
@@ -362,9 +359,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info)
}
gps->flag = GP_STROKE_3DSPACE;
gps->thickness = 3;
- /* assign color to stroke */
- BLI_strncpy(gps->colorname, palcolor->info, sizeof(gps->colorname));
- gps->palcolor = palcolor;
+
BLI_addtail(&gpf->strokes, gps);
changed = true;
}
@@ -461,7 +456,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
GPU_blend(true);
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -475,7 +470,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
immUniform1f("dash_width", 6.0f);
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2fv(shdr_pos, co_ss[0]);
immVertex2fv(shdr_pos, co_ss[1]);
@@ -517,7 +512,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
immUniformColor3ubv(color_wire);
- immBegin(GWN_PRIM_LINE_STRIP, arc_steps + 1);
+ immBegin(GPU_PRIM_LINE_STRIP, arc_steps + 1);
for (j = 0; j <= arc_steps; j++) {
madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale);
@@ -550,7 +545,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
immUniformColor3ubv(color_wire);
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
immVertex2fv(shdr_pos, cap);
@@ -614,7 +609,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
immUniform1f("dash_width", 6.0f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2fv(shdr_pos, co_ss[0]);
immVertex2fv(shdr_pos, co_ss[2]);
@@ -638,7 +633,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
immUniformColor3ubv(color_wire);
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
immVertex2fv(shdr_pos, cap);
@@ -703,7 +698,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
float co_ss[3];
ED_view3d_project_float_global(ar, ruler_item->co[ruler_item->co_index], co_ss, V3D_PROJ_TEST_NOP);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(color_act);
@@ -911,7 +906,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
BLI_listbase_is_empty(&ruler_info->items))
{
View3D *v3d = CTX_wm_view3d(C);
- const bool use_depth = (v3d->drawtype >= OB_SOLID);
+ const bool use_depth = (v3d->shading.type >= OB_SOLID);
/* Create new line */
RulerItem *ruler_item_prev = ruler_item_active_get(ruler_info);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 0f82dfa775c..2f65ad1fde4 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -44,6 +44,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_tracking_types.h"
+#include "DNA_gpencil_types.h"
#include "MEM_guardedalloc.h"
@@ -76,6 +77,7 @@
#include "BKE_editmesh.h"
#include "BKE_scene.h"
#include "BKE_tracking.h"
+#include "BKE_workspace.h"
#include "DEG_depsgraph.h"
@@ -95,6 +97,7 @@
#include "ED_screen.h"
#include "ED_sculpt.h"
#include "ED_mball.h"
+#include "ED_gpencil.h"
#include "UI_interface.h"
@@ -510,7 +513,7 @@ static void do_lasso_select_mesh(
/* for non zbuf projections, don't change the GL state */
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- gpuLoadMatrix(vc->rv3d->viewmat);
+ GPU_matrix_set(vc->rv3d->viewmat);
bbsel = EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
if (ts->selectmode & SCE_SELECT_VERTEX) {
@@ -1189,7 +1192,7 @@ static int mixed_bones_object_selectbuffer(
/* define if we use solid nearest select or not */
if (use_cycle) {
- if (v3d->drawtype > OB_WIRE) {
+ if (v3d->shading.type > OB_WIRE) {
do_nearest = true;
if (len_manhattan_v2v2_int(mval, last_mval) < 3) {
do_nearest = false;
@@ -1198,7 +1201,7 @@ static int mixed_bones_object_selectbuffer(
copy_v2_v2_int(last_mval, mval);
}
else {
- if (v3d->drawtype > OB_WIRE) {
+ if (v3d->shading.type > OB_WIRE) {
do_nearest = true;
}
}
@@ -1675,6 +1678,28 @@ static bool ed_object_select_pick(
if ((oldbasact != basact) && (is_obedit == false)) {
ED_object_base_activate(C, basact); /* adds notifier */
}
+
+ /* Set special modes for grease pencil
+ The grease pencil modes are not real modes, but a hack to make the interface
+ consistent, so need some tricks to keep UI synchronized */
+ // XXX: This stuff neeeds reviewing (Aligorith)
+ if (false &&
+ (((oldbasact) && oldbasact->object->type == OB_GPENCIL) ||
+ (basact->object->type == OB_GPENCIL)))
+ {
+ /* set cursor */
+ if (ELEM(basact->object->mode,
+ OB_MODE_GPENCIL_PAINT,
+ OB_MODE_GPENCIL_SCULPT,
+ OB_MODE_GPENCIL_WEIGHT))
+ {
+ ED_gpencil_toggle_brush_cursor(C, true, NULL);
+ }
+ else {
+ /* TODO: maybe is better use restore */
+ ED_gpencil_toggle_brush_cursor(C, false, NULL);
+ }
+ }
}
DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE);
@@ -1936,7 +1961,7 @@ static int do_mesh_box_select(
/* for non zbuf projections, don't change the GL state */
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- gpuLoadMatrix(vc->rv3d->viewmat);
+ GPU_matrix_set(vc->rv3d->viewmat);
bbsel = EDBM_backbuf_border_init(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
if (ts->selectmode & SCE_SELECT_VERTEX) {
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 7799854db49..15be77ff6ab 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -72,6 +72,7 @@ static bool snap_calc_active_center(bContext *C, const bool select_only, float r
/* *********************** operators ******************** */
+/** Snaps every individual object center to its nearest point on the grid. **/
static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
@@ -212,7 +213,7 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Selection to Grid";
- ot->description = "Snap selected item(s) to nearest grid division";
+ ot->description = "Snap selected item(s) to their nearest grid division";
ot->idname = "VIEW3D_OT_snap_selected_to_grid";
/* api callbacks */
@@ -220,11 +221,17 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
ot->poll = ED_operator_region_view3d_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
}
/* *************************************************** */
+/** Snaps the selection as a whole (use_offset=true) or each selected object to the given location.
+ *
+ * \param snap_target_global: a location in global space to snap to (eg. 3D cursor or active object).
+ * \param use_offset: if the selected objects should maintain their relative offsets and be snapped by the selection
+ * pivot point (median, active), or if every object origin should be snapped to the given location.
+**/
static int snap_selected_to_location(bContext *C, const float snap_target_global[3], const bool use_offset)
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
@@ -434,7 +441,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Selection to Cursor";
- ot->description = "Snap selected item(s) to cursor";
+ ot->description = "Snap selected item(s) to the 3D cursor";
ot->idname = "VIEW3D_OT_snap_selected_to_cursor";
/* api callbacks */
@@ -442,12 +449,16 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
ot->poll = ED_operator_view3d_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
/* rna */
- RNA_def_boolean(ot->srna, "use_offset", 1, "Offset", "");
+ RNA_def_boolean(ot->srna, "use_offset", 1, "Offset",
+ "If the selection should be snapped as a whole or by each object center");
}
+/* *************************************************** */
+
+/** Snaps each selected object to the location of the active selected object. **/
static int snap_selected_to_active_exec(bContext *C, wmOperator *op)
{
float snap_target_global[3];
@@ -472,12 +483,13 @@ void VIEW3D_OT_snap_selected_to_active(wmOperatorType *ot)
ot->poll = ED_operator_view3d_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
}
/* *************************************************** */
+/** Snaps the 3D cursor location to its nearest point on the grid. **/
static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
@@ -502,7 +514,7 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Cursor to Grid";
- ot->description = "Snap cursor to nearest grid division";
+ ot->description = "Snap 3D cursor to the nearest grid division";
ot->idname = "VIEW3D_OT_snap_cursor_to_grid";
/* api callbacks */
@@ -515,7 +527,8 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
/* **************************************************** */
-static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, float vec[3])
+/** Returns the center position of a tracking marker visible on the viewport (useful to snap to). **/
+static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, float r_vec[3])
{
MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
MovieTracking *tracking;
@@ -563,10 +576,11 @@ static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, floa
}
if (ok) {
- mid_v3_v3v3(vec, min, max);
+ mid_v3_v3v3(r_vec, min, max);
}
}
+/** Snaps the 3D cursor location to the median point of the selection. **/
static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
@@ -690,7 +704,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Cursor to Selected";
- ot->description = "Snap cursor to center of selected item(s)";
+ ot->description = "Snap 3D cursor to the middle of the selected item(s)";
ot->idname = "VIEW3D_OT_snap_cursor_to_selected";
/* api callbacks */
@@ -698,14 +712,16 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
ot->poll = ED_operator_view3d_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
}
/* ********************************************** */
-/* this could be exported to be a generic function
- * see: calculateCenterActive */
-
+/** Calculates the center position of the active object in global space.
+ *
+ * Note: this could be exported to be a generic function.
+ * see: calculateCenterActive
+**/
static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3])
{
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
@@ -770,7 +786,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Cursor to Active";
- ot->description = "Snap cursor to active item";
+ ot->description = "Snap 3D cursor to the active item";
ot->idname = "VIEW3D_OT_snap_cursor_to_active";
/* api callbacks */
@@ -778,11 +794,12 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
ot->poll = ED_operator_view3d_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
}
/* **************************************************** */
-/*New Code - Snap Cursor to Center -*/
+
+/** Snaps the 3D cursor location to the origin. **/
static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
@@ -802,7 +819,7 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Cursor to Center";
- ot->description = "Snap cursor to world origin";
+ ot->description = "Snap 3D cursor to the world origin";
ot->idname = "VIEW3D_OT_snap_cursor_to_center";
/* api callbacks */
@@ -815,23 +832,22 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot)
/* **************************************************** */
-
-bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3])
+/** Calculates the bounding box corners (min and max) for \a obedit. The returned values are in global space. **/
+bool ED_view3d_minmax_verts(Object *obedit, float r_min[3], float r_max[3])
{
TransVertStore tvs = {NULL};
TransVert *tv;
float centroid[3], vec[3], bmat[3][3];
- int a;
- /* metaballs are an exception */
+ /* Metaballs are an exception. */
if (obedit->type == OB_MBALL) {
float ob_min[3], ob_max[3];
bool changed;
changed = BKE_mball_minmax_ex(obedit->data, ob_min, ob_max, obedit->obmat, SELECT);
if (changed) {
- minmax_v3v3_v3(min, max, ob_min);
- minmax_v3v3_v3(min, max, ob_max);
+ minmax_v3v3_v3(r_min, r_max, ob_min);
+ minmax_v3v3_v3(r_min, r_max, ob_max);
}
return changed;
}
@@ -845,12 +861,12 @@ bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3])
copy_m3_m4(bmat, obedit->obmat);
tv = tvs.transverts;
- for (a = 0; a < tvs.transverts_tot; a++, tv++) {
+ for (int a = 0; a < tvs.transverts_tot; a++, tv++) {
copy_v3_v3(vec, (tv->flag & TX_VERT_USE_MAPLOC) ? tv->maploc : tv->loc);
mul_m3_v3(bmat, vec);
add_v3_v3(vec, obedit->obmat[3]);
add_v3_v3(centroid, vec);
- minmax_v3v3_v3(min, max, vec);
+ minmax_v3v3_v3(r_min, r_max, vec);
}
ED_transverts_free(&tvs);
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index ca5375b6b54..9b006bf4d9b 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -189,8 +189,8 @@ void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *ar)
RegionView3D *rv3d = ar->regiondata;
wmViewport(&ar->winrct); // TODO: bad
- gpuLoadProjectionMatrix(rv3d->winmat);
- gpuLoadMatrix(rv3d->viewmat);
+ GPU_matrix_projection_set(rv3d->winmat);
+ GPU_matrix_set(rv3d->viewmat);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index c9e915a6415..8a4a0efad2a 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -184,7 +184,7 @@ void ED_view3d_smooth_view_ex(
}
/* skip smooth viewing for render engine draw */
- if (smooth_viewtx && v3d->drawtype != OB_RENDER) {
+ if (smooth_viewtx && v3d->shading.type != OB_RENDER) {
bool changed = false; /* zero means no difference */
if (sview->camera_old != sview->camera)
@@ -721,14 +721,14 @@ void view3d_winmatrix_set(Depsgraph *depsgraph, ARegion *ar, const View3D *v3d,
}
if (is_ortho) {
- gpuOrtho(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+ GPU_matrix_ortho_set(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
}
else {
- gpuFrustum(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+ GPU_matrix_frustum_set(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
}
/* update matrix in 3d view region */
- gpuGetProjectionMatrix(rv3d->winmat);
+ GPU_matrix_projection_get(rv3d->winmat);
}
static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
@@ -1003,7 +1003,7 @@ int view3d_opengl_select(
* the object & bone view locking takes 'rect' into account, see: T51629. */
ED_view3d_draw_setup_view(vc->win, depsgraph, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect);
- if (v3d->drawtype > OB_WIRE) {
+ if (v3d->shading.type > OB_WIRE) {
GPU_depth_test(true);
}
@@ -1048,7 +1048,7 @@ int view3d_opengl_select(
G.f &= ~G_PICKSEL;
ED_view3d_draw_setup_view(vc->win, depsgraph, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
- if (v3d->drawtype > OB_WIRE) {
+ if (v3d->shading.type > OB_WIRE) {
GPU_depth_test(false);
}
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 4c5150fabdd..e4e12cc3686 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -343,14 +343,14 @@ static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *ar, void *a
yoff = walk->ar->winy / 2;
}
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_VIEW_OVERLAY);
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
/* North */
immVertex2i(pos, xoff, yoff + inner_length);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index ad7b5d55ba5..142460bb7fa 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -41,9 +41,11 @@
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_mask_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h" /* PET modes */
#include "DNA_workspace_types.h"
+#include "DNA_gpencil_types.h"
#include "BLI_alloca.h"
#include "BLI_utildefines.h"
@@ -64,6 +66,7 @@
#include "BKE_unit.h"
#include "BKE_scene.h"
#include "BKE_mask.h"
+#include "BKE_mesh.h"
#include "BKE_report.h"
#include "BKE_workspace.h"
@@ -85,6 +88,7 @@
#include "ED_mesh.h"
#include "ED_clip.h"
#include "ED_node.h"
+#include "ED_gpencil.h"
#include "WM_types.h"
#include "WM_api.h"
@@ -95,6 +99,7 @@
#include "UI_resources.h"
#include "RNA_access.h"
+#include "RNA_define.h"
#include "BLF_api.h"
#include "BLT_translation.h"
@@ -115,6 +120,7 @@ static void postInputRotation(TransInfo *t, float values[3]);
static void ElementRotation(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const short around);
static void initSnapSpatial(TransInfo *t, float r_snap[3]);
+static void storeCustomLNorValue(TransDataContainer *t, BMesh *bm);
/* Transform Callbacks */
static void initBend(TransInfo *t);
@@ -140,6 +146,9 @@ static void applyToSphere(TransInfo *t, const int mval[2]);
static void initRotation(TransInfo *t);
static void applyRotation(TransInfo *t, const int mval[2]);
+static void initNormalRotation(TransInfo *t);
+static void applyNormalRotation(TransInfo *t, const int mval[2]);
+
static void initShrinkFatten(TransInfo *t);
static void applyShrinkFatten(TransInfo *t, const int mval[2]);
@@ -571,6 +580,10 @@ void removeAspectRatio(TransInfo *t, float vec[2])
static void viewRedrawForce(const bContext *C, TransInfo *t)
{
if (t->options & CTX_GPENCIL_STROKES) {
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ if (gpd) {
+ DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
+ }
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
}
else if (t->spacetype == SPACE_VIEW3D) {
@@ -1546,6 +1559,18 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
break;
+ case NKEY:
+ if (ELEM(t->mode, TFM_ROTATION)) {
+ if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) {
+ restoreTransObjects(t);
+ resetTransModal(t);
+ resetTransRestrictions(t);
+ initNormalRotation(t);
+ t->redraw = TREDRAW_HARD;
+ handled = true;
+ }
+ }
+ break;
default:
break;
}
@@ -1689,13 +1714,13 @@ typedef enum {
} ArrowDirection;
#define POS_INDEX 0
-/* NOTE: this --^ is a bit hackish, but simplifies Gwn_VertFormat usage among functions
+/* NOTE: this --^ is a bit hackish, but simplifies GPUVertFormat usage among functions
* private to this file - merwin
*/
static void drawArrow(ArrowDirection d, short offset, short length, short size)
{
- immBegin(GWN_PRIM_LINES, 6);
+ immBegin(GPU_PRIM_LINES, 6);
switch (d) {
case LEFT:
@@ -1732,7 +1757,7 @@ static void drawArrow(ArrowDirection d, short offset, short length, short size)
static void drawArrowHead(ArrowDirection d, short size)
{
- immBegin(GWN_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
switch (d) {
case LEFT:
@@ -1765,7 +1790,7 @@ static void drawArc(float size, float angle_start, float angle_end, int segments
float angle;
int a;
- immBegin(GWN_PRIM_LINE_STRIP, segments + 1);
+ immBegin(GPU_PRIM_LINE_STRIP, segments + 1);
for (angle = angle_start, a = 0; a < segments; angle += delta, a++) {
immVertex2f(POS_INDEX, cosf(angle) * size, sinf(angle) * size);
@@ -1784,7 +1809,7 @@ static bool helpline_poll(bContext *C)
return 0;
}
-static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
+static void drawHelpline(bContext *C, int x, int y, void *customdata)
{
TransInfo *t = (TransInfo *)customdata;
@@ -1800,7 +1825,31 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
(float)t->mval[1],
};
- projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
+ /* grease pencil only can edit one object at time because GP has
+ * multiframe edition that replaces multiobject edition.
+ * If multiobject edition is added, maybe this code will need
+ * an update
+ */
+ if ((t->flag & T_POINTS) && (t->options & CTX_GPENCIL_STROKES) &&
+ (t->around != V3D_AROUND_ACTIVE))
+ {
+ Object *ob = CTX_data_active_object(C);
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ FOREACH_TRANS_DATA_CONTAINER(t, tc) {
+ float vecrot[3];
+ copy_v3_v3(vecrot, t->center_global);
+ mul_m4_v3(ob->obmat, vecrot);
+ projectFloatViewEx(t, vecrot, cent, V3D_PROJ_TEST_CLIP_ZERO);
+ }
+ }
+ else {
+ /* normally, never must be used */
+ projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
+ }
+ }
+ else {
+ projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
+ }
/* Offset the values for the area region. */
const float offset[2] = {
@@ -1813,11 +1862,11 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
tmval[i] += offset[i];
}
- gpuPushMatrix();
+ GPU_matrix_push();
/* Dashed lines first. */
if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
UNUSED_VARS_NDEBUG(shdr_pos); /* silence warning */
BLI_assert(shdr_pos == POS_INDEX);
@@ -1835,7 +1884,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
immUniform1f("dash_width", 6.0f);
immUniform1f("dash_factor", 0.5f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2fv(POS_INDEX, cent);
immVertex2f(POS_INDEX, tmval[0], tmval[1]);
immEnd();
@@ -1844,7 +1893,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
}
/* And now, solid lines. */
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
UNUSED_VARS_NDEBUG(pos); /* silence warning */
BLI_assert(pos == POS_INDEX);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1853,8 +1902,8 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
case HLP_SPRING:
immUniformThemeColor(TH_VIEW_OVERLAY);
- gpuTranslate3fv(mval);
- gpuRotateAxis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z');
+ GPU_matrix_translate_3fv(mval);
+ GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z');
GPU_line_width(3.0f);
drawArrow(UP, 5, 10, 5);
@@ -1862,7 +1911,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
break;
case HLP_HARROW:
immUniformThemeColor(TH_VIEW_OVERLAY);
- gpuTranslate3fv(mval);
+ GPU_matrix_translate_3fv(mval);
GPU_line_width(3.0f);
drawArrow(RIGHT, 5, 10, 5);
@@ -1871,7 +1920,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
case HLP_VARROW:
immUniformThemeColor(TH_VIEW_OVERLAY);
- gpuTranslate3fv(mval);
+ GPU_matrix_translate_3fv(mval);
GPU_line_width(3.0f);
drawArrow(UP, 5, 10, 5);
@@ -1887,23 +1936,23 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
immUniformThemeColor(TH_VIEW_OVERLAY);
- gpuTranslate3f(cent[0] - tmval[0] + mval[0], cent[1] - tmval[1] + mval[1], 0);
+ GPU_matrix_translate_3f(cent[0] - tmval[0] + mval[0], cent[1] - tmval[1] + mval[1], 0);
GPU_line_width(3.0f);
drawArc(dist, angle - delta_angle, angle - spacing_angle, 10);
drawArc(dist, angle + spacing_angle, angle + delta_angle, 10);
- gpuPushMatrix();
+ GPU_matrix_push();
- gpuTranslate3f(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
- gpuRotateAxis(RAD2DEGF(angle - delta_angle), 'Z');
+ GPU_matrix_translate_3f(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
+ GPU_matrix_rotate_axis(RAD2DEGF(angle - delta_angle), 'Z');
drawArrowHead(DOWN, 5);
- gpuPopMatrix();
+ GPU_matrix_pop();
- gpuTranslate3f(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
- gpuRotateAxis(RAD2DEGF(angle + delta_angle), 'Z');
+ GPU_matrix_translate_3f(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
+ GPU_matrix_rotate_axis(RAD2DEGF(angle + delta_angle), 'Z');
drawArrowHead(UP, 5);
break;
@@ -1913,7 +1962,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
unsigned char col[3], col2[3];
UI_GetThemeColor3ubv(TH_GRID, col);
- gpuTranslate3fv(mval);
+ GPU_matrix_translate_3fv(mval);
GPU_line_width(3.0f);
@@ -1933,7 +1982,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
}
immUnbindProgram();
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
@@ -2153,7 +2202,11 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
}
- RNA_property_boolean_set_array(op->ptr, prop, constraint_axis);
+ /* Only set if needed, so we can hide in the UI when nothing is set.
+ * See 'transform_poll_property'. */
+ if (ELEM(true, UNPACK3(constraint_axis))) {
+ RNA_property_boolean_set_array(op->ptr, prop, constraint_axis);
+ }
}
{
@@ -2501,6 +2554,9 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
case TFM_SEQ_SLIDE:
initSeqSlide(t);
break;
+ case TFM_NORMAL_ROTATION:
+ initNormalRotation(t);
+ break;
}
if (t->state == TRANS_CANCEL) {
@@ -2508,6 +2564,39 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
return 0;
}
+ if ((prop = RNA_struct_find_property(op->ptr, "preserve_clnor"))) {
+ if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) {
+
+ FOREACH_TRANS_DATA_CONTAINER(t, tc) {
+ if ((((Mesh *)(tc->obedit->data))->flag & ME_AUTOSMOOTH)) {
+ BMEditMesh *em = NULL;// BKE_editmesh_from_object(t->obedit);
+ bool do_skip = false;
+
+ /* Currently only used for two of three most frequent transform ops, can include more ops.
+ * Note that scaling cannot be included here, non-uniform scaling will affect normals. */
+ if (ELEM(t->mode, TFM_TRANSLATION, TFM_ROTATION)) {
+ if (em->bm->totvertsel == em->bm->totvert) {
+ /* No need to invalidate if whole mesh is selected. */
+ do_skip = true;
+ }
+ }
+
+ if (t->flag & T_MODAL) {
+ RNA_property_boolean_set(op->ptr, prop, false);
+ }
+ else if (!do_skip) {
+ const bool preserve_clnor = RNA_property_boolean_get(op->ptr, prop);
+ if (preserve_clnor) {
+ BKE_editmesh_lnorspace_update(em);
+ t->flag |= T_CLNOR_REBUILD;
+ }
+ BM_lnorspace_invalidate(em->bm, true);
+ }
+ }
+ }
+ }
+ }
+
t->context = NULL;
return 1;
@@ -2568,6 +2657,12 @@ int transformEnd(bContext *C, TransInfo *t)
restoreTransObjects(t); // calls recalcData()
}
else {
+ if (t->flag & T_CLNOR_REBUILD) {
+ FOREACH_TRANS_DATA_CONTAINER(t, tc) {
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BM_lnorspace_rebuild(em->bm, true);
+ }
+ }
exit_code = OPERATOR_FINISHED;
}
@@ -3547,7 +3642,25 @@ static void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, f
else
sub_v3_v3(vec, td->center);
- mul_v3_fl(vec, td->factor);
+ /* grease pencil falloff */
+ if (t->options & CTX_GPENCIL_STROKES) {
+ bGPDstroke *gps = (bGPDstroke *)td->extra;
+ mul_v3_fl(vec, td->factor * gps->runtime.multi_frame_falloff);
+
+ /* scale stroke thickness */
+ if (td->val) {
+ snapGridIncrement(t, t->values);
+ applyNumInput(&t->num, t->values);
+
+ float ratio = t->values[0];
+ *td->val = td->ival * ratio * gps->runtime.multi_frame_falloff;
+ CLAMP_MIN(*td->val, 0.001f);
+ }
+
+ }
+ else {
+ mul_v3_fl(vec, td->factor);
+ }
if (t->flag & (T_OBJECT | T_POSE)) {
mul_m3_v3(td->smtx, vec);
@@ -3886,6 +3999,28 @@ static void initRotation(TransInfo *t)
copy_v3_v3(t->axis_orig, t->axis);
}
+/* Used by Transform Rotation and Transform Normal Rotation */
+static void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final)
+{
+ size_t ofs = 0;
+
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN];
+
+ outputNumInput(&(t->num), c, &t->scene->unit);
+
+ ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
+ }
+ else {
+ ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Rot: %.2f%s %s"),
+ RAD2DEGF(final), t->con.text, t->proptext);
+ }
+
+ if (t->flag & T_PROP_EDIT_ALL) {
+ ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ }
+}
+
/**
* Applies values of rotation to `td->loc` and `td->ext->quat`
* based on a rotation matrix (mat) and a pivot (center).
@@ -3901,6 +4036,20 @@ static void ElementRotation_ex(TransInfo *t, TransDataContainer *tc, TransData *
mul_m3_m3m3(totmat, mat, td->mtx);
mul_m3_m3m3(smat, td->smtx, totmat);
+ /* apply gpencil falloff */
+ if (t->options & CTX_GPENCIL_STROKES) {
+ bGPDstroke *gps = (bGPDstroke *)td->extra;
+ float sx = smat[0][0];
+ float sy = smat[1][1];
+ float sz = smat[2][2];
+
+ mul_m3_fl(smat, gps->runtime.multi_frame_falloff);
+ /* fix scale */
+ smat[0][0] = sx;
+ smat[1][1] = sy;
+ smat[2][2] = sz;
+ }
+
sub_v3_v3v3(vec, td->iloc, center);
mul_m3_v3(smat, vec);
@@ -4149,7 +4298,6 @@ static void applyRotationValue(TransInfo *t, float angle, float axis[3])
static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
- size_t ofs = 0;
float final;
@@ -4172,21 +4320,7 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
t->values[0] = final;
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
-
- outputNumInput(&(t->num), c, &t->scene->unit);
-
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
- }
- else {
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Rot: %.2f%s %s"),
- RAD2DEGF(final), t->con.text, t->proptext);
- }
-
- if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
- }
+ headerRotation(t, str, final);
applyRotationValue(t, final, t->axis);
@@ -4315,6 +4449,127 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
/* -------------------------------------------------------------------- */
+/* Transform (Normal Rotation) */
+
+/** \name Transform Normal Rotation
+* \{ */
+
+static void storeCustomLNorValue(TransDataContainer *tc, BMesh *bm)
+{
+ BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
+ // BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
+
+ tc->custom.mode.data = lnors_ed_arr;
+ tc->custom.mode.free_cb = freeCustomNormalArray;
+}
+
+void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
+{
+ BMLoopNorEditDataArray *lnors_ed_arr = custom_data->data;
+
+ if (t->state == TRANS_CANCEL) {
+ BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BMesh *bm = em->bm;
+
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { /* Restore custom loop normal on cancel */
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->niloc, lnor_ed->clnors_data);
+ }
+ }
+
+ BM_loop_normal_editdata_array_free(lnors_ed_arr);
+
+ tc->custom.mode.data = NULL;
+ tc->custom.mode.free_cb = NULL;
+}
+
+static void initNormalRotation(TransInfo *t)
+{
+ t->mode = TFM_NORMAL_ROTATION;
+ t->transform = applyNormalRotation;
+
+ setInputPostFct(&t->mouse, postInputRotation);
+ initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
+
+ t->idx_max = 0;
+ t->num.idx_max = 0;
+ t->snap[0] = 0.0f;
+ t->snap[1] = DEG2RAD(5.0);
+ t->snap[2] = DEG2RAD(1.0);
+
+ copy_v3_fl(t->num.val_inc, t->snap[2]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
+ t->num.unit_type[0] = B_UNIT_ROTATION;
+
+ FOREACH_TRANS_DATA_CONTAINER(t, tc) {
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BMesh *bm = em->bm;
+
+ BKE_editmesh_lnorspace_update(em);
+
+ storeCustomLNorValue(tc, bm);
+ }
+
+ negate_v3_v3(t->axis, t->viewinv[2]);
+ normalize_v3(t->axis);
+
+ copy_v3_v3(t->axis_orig, t->axis);
+}
+
+/* Works by getting custom normal from clnor_data, transform, then store */
+static void applyNormalRotation(TransInfo *t, const int UNUSED(mval[2]))
+{
+ char str[UI_MAX_DRAW_STR];
+
+ if ((t->con.mode & CON_APPLY) && t->con.applyRot) {
+ t->con.applyRot(t, NULL, NULL, t->axis, NULL);
+ }
+ else {
+ /* reset axis if constraint is not set */
+ copy_v3_v3(t->axis, t->axis_orig);
+ }
+
+ FOREACH_TRANS_DATA_CONTAINER(t, tc) {
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BMesh *bm = em->bm;
+
+ BMLoopNorEditDataArray *lnors_ed_arr = tc->custom.mode.data;
+ BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
+
+ float axis[3];
+ float mat[3][3];
+ float angle = t->values[0];
+ copy_v3_v3(axis, t->axis);
+
+ snapGridIncrement(t, &angle);
+
+ applySnapping(t, &angle);
+
+ applyNumInput(&t->num, &angle);
+
+ headerRotation(t, str, angle);
+
+ axis_angle_normalized_to_mat3(mat, axis, angle);
+
+ for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
+ mul_v3_m3v3(lnor_ed->nloc, mat, lnor_ed->niloc);
+
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data);
+ }
+ }
+
+ recalcData(t);
+
+ ED_area_status_text(t->sa, str);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
/* Transform (Translation) */
static void initSnapSpatial(TransInfo *t, float r_snap[3])
@@ -4574,7 +4829,21 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
}
mul_m3_v3(td->smtx, tvec);
- mul_v3_fl(tvec, td->factor);
+
+ if (t->options & CTX_GPENCIL_STROKES) {
+ /* grease pencil multiframe falloff */
+ bGPDstroke *gps = (bGPDstroke *)td->extra;
+ if (gps != NULL) {
+ mul_v3_fl(tvec, td->factor * gps->runtime.multi_frame_falloff);
+ }
+ else {
+ mul_v3_fl(tvec, td->factor);
+ }
+ }
+ else {
+ /* proportional editing falloff */
+ mul_v3_fl(tvec, td->factor);
+ }
protectedTransBits(td->protectflag, tvec);
@@ -6654,7 +6923,7 @@ static bool createEdgeSlideVerts_double_side(TransInfo *t, TransDataContainer *t
if (t->spacetype == SPACE_VIEW3D) {
v3d = t->sa ? t->sa->spacedata.first : NULL;
rv3d = t->ar ? t->ar->regiondata : NULL;
- use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE);
+ use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && v3d->shading.type > OB_WIRE);
}
calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, true);
@@ -6849,7 +7118,7 @@ static bool createEdgeSlideVerts_single_side(TransInfo *t, TransDataContainer *t
if (t->spacetype == SPACE_VIEW3D) {
v3d = t->sa ? t->sa->spacedata.first : NULL;
rv3d = t->ar ? t->ar->regiondata : NULL;
- use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE);
+ use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && v3d->shading.type > OB_WIRE);
}
calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, false);
@@ -7049,10 +7318,10 @@ static void drawEdgeSlide(TransInfo *t)
GPU_blend(true);
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- gpuPushMatrix();
- gpuMultMatrix(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
+ GPU_matrix_push();
+ GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -7069,7 +7338,7 @@ static void drawEdgeSlide(TransInfo *t)
GPU_line_width(line_size);
immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- immBeginAtMost(GWN_PRIM_LINES, 4);
+ 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);
@@ -7082,7 +7351,7 @@ static void drawEdgeSlide(TransInfo *t)
immUniformThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
GPU_point_size(ctrl_size);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
if (slp->flipped) {
if (curr_sv->v_side[1]) immVertex3fv(pos, curr_sv->v_side[1]->co);
}
@@ -7093,7 +7362,7 @@ static void drawEdgeSlide(TransInfo *t)
immUniformThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
GPU_point_size(guide_size);
- immBegin(GWN_PRIM_POINTS, 1);
+ 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();
@@ -7107,7 +7376,7 @@ static void drawEdgeSlide(TransInfo *t)
GPU_line_width(line_size);
immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- immBegin(GWN_PRIM_LINES, sld->totsv * 2);
+ immBegin(GPU_PRIM_LINES, sld->totsv * 2);
/* TODO(campbell): Loop over all verts */
sv = sld->sv;
@@ -7138,7 +7407,7 @@ static void drawEdgeSlide(TransInfo *t)
immUnbindProgram();
- gpuPopMatrix();
+ GPU_matrix_pop();
GPU_blend(false);
@@ -7682,17 +7951,17 @@ static void drawVertSlide(TransInfo *t)
GPU_blend(true);
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- gpuPushMatrix();
- gpuMultMatrix(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
+ GPU_matrix_push();
+ GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
GPU_line_width(line_size);
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- immBegin(GWN_PRIM_LINES, sld->totsv * 2);
+ immBegin(GPU_PRIM_LINES, sld->totsv * 2);
if (is_clamp) {
sv = sld->sv;
for (i = 0; i < sld->totsv; i++, sv++) {
@@ -7718,7 +7987,7 @@ static void drawVertSlide(TransInfo *t)
GPU_point_size(ctrl_size);
- immBegin(GWN_PRIM_POINTS, 1);
+ immBegin(GPU_PRIM_POINTS, 1);
immVertex3fv(shdr_pos, (slp->flipped && slp->use_even) ?
curr_sv->co_link_orig_3d[curr_sv->co_link_curr] :
curr_sv->co_orig_3d);
@@ -7761,7 +8030,7 @@ static void drawVertSlide(TransInfo *t)
immUniform1f("dash_width", 6.0f);
immUniform1f("dash_factor", 0.5f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(shdr_pos, curr_sv->co_orig_3d);
immVertex3fv(shdr_pos, co_dest_3d);
immEnd();
@@ -7769,7 +8038,7 @@ static void drawVertSlide(TransInfo *t)
immUnbindProgram();
}
- gpuPopMatrix();
+ GPU_matrix_pop();
GPU_depth_test(true);
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 2006bd830b4..dfcd3e4cfd6 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -505,7 +505,7 @@ typedef struct TransInfo {
short current_orientation;
TransformOrientation *custom_orientation; /* this gets used when current_orientation is V3D_MANIP_CUSTOM */
- short mpr_flag; /* backup from view3d, to restore on end */
+ short gizmo_flag; /* backup from view3d, to restore on end */
short prop_mode;
@@ -609,6 +609,8 @@ typedef struct TransInfo {
#define T_MODAL_CURSOR_SET (1 << 26)
+#define T_CLNOR_REBUILD (1 << 27)
+
/* TransInfo->modifiers */
#define MOD_CONSTRAINT_SELECT 0x01
#define MOD_PRECISION 0x02
@@ -877,6 +879,8 @@ bool applyTransformOrientation(const struct TransformOrientation *ts, float r_ma
int getTransformOrientation_ex(const struct bContext *C, float normal[3], float plane[3], const short around);
int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3]);
+void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data);
+
void freeEdgeSlideTempFaces(EdgeSlideData *sld);
void freeEdgeSlideVerts(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data);
void projectEdgeSlideData(TransInfo *t, bool is_final);
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index d40602f8d43..b24ef4e0ba2 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -560,7 +560,9 @@ static void applyObjectConstraintRot(
/* on setup call, use first object */
if (td == NULL) {
- td = TRANS_DATA_CONTAINER_FIRST_OK(t)->data;
+ BLI_assert(tc == NULL);
+ tc = TRANS_DATA_CONTAINER_FIRST_OK(t);
+ td = tc->data;
}
if (t->flag & T_EDIT) {
@@ -747,7 +749,7 @@ void drawConstraint(TransInfo *t)
if (depth_test_enabled)
GPU_depth_test(false);
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
@@ -760,7 +762,7 @@ void drawConstraint(TransInfo *t)
immUniform1f("dash_width", 2.0f);
immUniform1f("dash_factor", 0.5f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(shdr_pos, t->center_global);
immVertex3fv(shdr_pos, vec);
immEnd();
@@ -800,13 +802,13 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
unit_m4(imat);
}
- gpuPushMatrix();
+ GPU_matrix_push();
if (t->spacetype == SPACE_VIEW3D) {
/* pass */
}
else if (t->spacetype == SPACE_IMAGE) {
- gpuScale2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]);
+ GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]);
}
else if (ELEM(t->spacetype, SPACE_IPO, SPACE_ACTION)) {
/* only scale y */
@@ -816,14 +818,14 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
float ysize = BLI_rctf_size_y(datamask);
float xmask = BLI_rcti_size_x(mask);
float ymask = BLI_rcti_size_y(mask);
- gpuScale2f(1.0f, (ysize / xsize) * (xmask / ymask));
+ GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask));
}
depth_test_enabled = GPU_depth_test_enabled();
if (depth_test_enabled)
GPU_depth_test(false);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformThemeColor(TH_GRID);
@@ -837,7 +839,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
if (depth_test_enabled)
GPU_depth_test(true);
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index a5706f4a003..d3b7417c4dd 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -90,6 +90,7 @@
#include "BKE_editmesh.h"
#include "BKE_tracking.h"
#include "BKE_mask.h"
+#include "BKE_colortools.h"
#include "BIK_api.h"
@@ -747,7 +748,7 @@ static void bone_children_clear_transflag(int mode, short around, ListBase *lb)
/* sets transform flags in the bones
* returns total number of bones with BONE_TRANSFORM */
-int count_set_pose_transflags(Object *ob, const int mode, short around, bool has_translate_rotate[2])
+int count_set_pose_transflags(Object *ob, const int mode, const short around, bool has_translate_rotate[2])
{
bArmature *arm = ob->data;
bPoseChannel *pchan;
@@ -3609,6 +3610,8 @@ static void posttrans_gpd_clean(bGPdata *gpd)
}
#endif
}
+ /* set cache flag to dirty */
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
}
static void posttrans_mask_clean(Mask *mask)
@@ -8086,7 +8089,14 @@ void flushTransPaintCurve(TransInfo *t)
static void createTransGPencil(bContext *C, TransInfo *t)
{
+ Depsgraph *depsgraph = CTX_data_depsgraph(C); \
bGPdata *gpd = ED_gpencil_data_get_active(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+
+ bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ bool use_multiframe_falloff = (ts->gp_sculpt.flag & GP_BRUSHEDIT_FLAG_FRAME_FALLOFF) != 0;
+
+ Object *obact = CTX_data_active_object(C);
bGPDlayer *gpl;
TransData *td = NULL;
float mtx[3][3], smtx[3][3];
@@ -8110,50 +8120,67 @@ static void createTransGPencil(bContext *C, TransInfo *t)
if (gpd == NULL)
return;
+ /* initialize falloff curve */
+ if (is_multiedit) {
+ curvemapping_initialize(ts->gp_sculpt.cur_falloff);
+ }
+
/* First Pass: Count the number of datapoints required for the strokes,
* (and additional info about the configuration - e.g. 2D/3D?)
*/
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* only editable and visible layers are considered */
if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
- bGPDframe *gpf = gpl->actframe;
+ bGPDframe *gpf;
bGPDstroke *gps;
+ bGPDframe *init_gpf = gpl->actframe;
+ if (is_multiedit) {
+ init_gpf = gpl->frames.first;
+ }
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false) {
- continue;
- }
- /* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
- continue;
- }
+ for (gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ continue;
+ }
- if (is_prop_edit) {
- /* Proportional Editing... */
- if (is_prop_edit_connected) {
- /* connected only - so only if selected */
- if (gps->flag & GP_STROKE_SELECT)
- tc->data_len += gps->totpoints;
- }
- else {
- /* everything goes - connection status doesn't matter */
- tc->data_len += gps->totpoints;
- }
- }
- else {
- /* only selected stroke points are considered */
- if (gps->flag & GP_STROKE_SELECT) {
- bGPDspoint *pt;
- int i;
-
- // TODO: 2D vs 3D?
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if (pt->flag & GP_SPOINT_SELECT)
- tc->data_len++;
+ if (is_prop_edit) {
+ /* Proportional Editing... */
+ if (is_prop_edit_connected) {
+ /* connected only - so only if selected */
+ if (gps->flag & GP_STROKE_SELECT)
+ tc->data_len += gps->totpoints;
+ }
+ else {
+ /* everything goes - connection status doesn't matter */
+ tc->data_len += gps->totpoints;
+ }
+ }
+ else {
+ /* only selected stroke points are considered */
+ if (gps->flag & GP_STROKE_SELECT) {
+ bGPDspoint *pt;
+ int i;
+
+ // TODO: 2D vs 3D?
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT)
+ tc->data_len++;
+ }
+ }
}
}
}
+ /* if not multiedit out of loop */
+ if (!is_multiedit) {
+ break;
+ }
}
}
}
@@ -8180,153 +8207,166 @@ static void createTransGPencil(bContext *C, TransInfo *t)
float diff_mat[4][4];
float inverse_diff_mat[4][4];
- /* calculate difference matrix if parent object */
- if (gpl->parent != NULL) {
- ED_gpencil_parent_location(gpl, diff_mat);
- /* undo matrix */
- invert_m4_m4(inverse_diff_mat, diff_mat);
+ bGPDframe *init_gpf = gpl->actframe;
+ if (is_multiedit) {
+ init_gpf = gpl->frames.first;
}
+ /* init multiframe falloff options */
+ int f_init = 0;
+ int f_end = 0;
+
+ if (use_multiframe_falloff) {
+ BKE_gpencil_get_range_selected(gpl, &f_init, &f_end);
+ }
+
+ /* calculate difference matrix */
+ ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat);
+ /* undo matrix */
+ invert_m4_m4(inverse_diff_mat, diff_mat);
/* Make a new frame to work on if the layer's frame and the current scene frame don't match up
* - This is useful when animating as it saves that "uh-oh" moment when you realize you've
* spent too much time editing the wrong frame...
*/
- if (gpf->framenum != cfra) {
+ // XXX: should this be allowed when framelock is enabled?
+ if ((gpf->framenum != cfra) && (!is_multiedit)) {
gpf = BKE_gpencil_frame_addcopy(gpl, cfra);
/* in some weird situations (framelock enabled) return NULL */
if (gpf == NULL) {
continue;
}
+ if (!is_multiedit) {
+ init_gpf = gpf;
+ }
}
/* Loop over strokes, adding TransData for points as needed... */
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
- TransData *head = td;
- TransData *tail = td;
- bool stroke_ok;
-
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false) {
- continue;
- }
- /* check if the color is editable */
- if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
- continue;
- }
- /* What we need to include depends on proportional editing settings... */
- if (is_prop_edit) {
- if (is_prop_edit_connected) {
- /* A) "Connected" - Only those in selected strokes */
- stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0;
- }
- else {
- /* B) All points, always */
- stroke_ok = true;
- }
- }
- else {
- /* C) Only selected points in selected strokes */
- stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0;
- }
-
- /* Do stroke... */
- if (stroke_ok && gps->totpoints) {
- bGPDspoint *pt;
- int i;
-
-#if 0 /* XXX: this isn't needed anymore; cannot calculate center this way or is_prop_edit breaks */
- const float ninv = 1.0f / gps->totpoints;
- float center[3] = {0.0f};
-
- /* compute midpoint of stroke */
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- madd_v3_v3v3fl(center, center, &pt->x, ninv);
+ for (gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+
+ /* if multiframe and falloff, recalculate and save value */
+ float falloff = 1.0f; /* by default no falloff */
+ if ((is_multiedit) && (use_multiframe_falloff)) {
+ /* Faloff depends on distance to active frame (relative to the overall frame range) */
+ falloff = BKE_gpencil_multiframe_falloff_calc(gpf, gpl->actframe->framenum,
+ f_init, f_end, ts->gp_sculpt.cur_falloff);
}
-#endif
- /* add all necessary points... */
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- bool point_ok;
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ TransData *head = td;
+ TransData *tail = td;
+ bool stroke_ok;
- /* include point? */
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ continue;
+ }
+ /* What we need to include depends on proportional editing settings... */
if (is_prop_edit) {
- /* Always all points in strokes that get included */
- point_ok = true;
+ if (is_prop_edit_connected) {
+ /* A) "Connected" - Only those in selected strokes */
+ stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0;
+ }
+ else {
+ /* B) All points, always */
+ stroke_ok = true;
+ }
}
else {
- /* Only selected points in selected strokes */
- point_ok = (pt->flag & GP_SPOINT_SELECT) != 0;
+ /* C) Only selected points in selected strokes */
+ stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0;
}
- /* do point... */
- if (point_ok) {
- copy_v3_v3(td->iloc, &pt->x);
- copy_v3_v3(td->center, &pt->x); // XXX: what about t->around == local?
-
- td->loc = &pt->x;
-
- td->flag = 0;
+ /* Do stroke... */
+ if (stroke_ok && gps->totpoints) {
+ bGPDspoint *pt;
+ int i;
- if (pt->flag & GP_SPOINT_SELECT)
- td->flag |= TD_SELECTED;
-
- /* for other transform modes (e.g. shrink-fatten), need to additional data */
- if (t->mode == TFM_GPENCIL_SHRINKFATTEN) {
- td->val = &pt->pressure;
- td->ival = pt->pressure;
- }
+ /* save falloff factor */
+ gps->runtime.multi_frame_falloff = falloff;
- /* screenspace needs special matrices... */
- if ((gps->flag & (GP_STROKE_3DSPACE | GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) == 0) {
- /* screenspace */
- td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ;
+ /* add all necessary points... */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ bool point_ok;
- /* apply parent transformations */
- if (gpl->parent == NULL) {
- copy_m3_m4(td->smtx, t->persmat);
- copy_m3_m4(td->mtx, t->persinv);
- unit_m3(td->axismtx);
+ /* include point? */
+ if (is_prop_edit) {
+ /* Always all points in strokes that get included */
+ point_ok = true;
}
else {
- /* apply matrix transformation relative to parent */
- copy_m3_m4(td->smtx, inverse_diff_mat); /* final position */
- copy_m3_m4(td->mtx, diff_mat); /* display position */
- copy_m3_m4(td->axismtx, diff_mat); /* axis orientation */
- }
- }
- else {
- /* configure 2D dataspace points so that they don't play up... */
- if (gps->flag & (GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) {
- td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ;
- // XXX: matrices may need to be different?
+ /* Only selected points in selected strokes */
+ point_ok = (pt->flag & GP_SPOINT_SELECT) != 0;
}
- /* apply parent transformations */
- if (gpl->parent == NULL) {
- copy_m3_m3(td->smtx, smtx);
- copy_m3_m3(td->mtx, mtx);
- unit_m3(td->axismtx); // XXX?
- }
- else {
- /* apply matrix transformation relative to parent */
- copy_m3_m4(td->smtx, inverse_diff_mat); /* final position */
- copy_m3_m4(td->mtx, diff_mat); /* display position */
- copy_m3_m4(td->axismtx, diff_mat); /* axis orientation */
+ /* do point... */
+ if (point_ok) {
+ copy_v3_v3(td->iloc, &pt->x);
+ copy_v3_v3(td->center, &pt->x); // XXX: what about t->around == local?
+
+ td->loc = &pt->x;
+
+ td->flag = 0;
+
+ if (pt->flag & GP_SPOINT_SELECT)
+ td->flag |= TD_SELECTED;
+
+ /* for other transform modes (e.g. shrink-fatten), need to additional data
+ * but never for scale or mirror
+ */
+ if ((t->mode != TFM_RESIZE) && (t->mode != TFM_MIRROR)) {
+ td->val = &pt->pressure;
+ td->ival = pt->pressure;
+ }
+
+ /* screenspace needs special matrices... */
+ if ((gps->flag & (GP_STROKE_3DSPACE | GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) == 0) {
+ /* screenspace */
+ td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ;
+
+ /* apply matrix transformation relative to parent */
+ copy_m3_m4(td->smtx, inverse_diff_mat); /* final position */
+ copy_m3_m4(td->mtx, diff_mat); /* display position */
+ copy_m3_m4(td->axismtx, diff_mat); /* axis orientation */
+ }
+ else {
+ /* configure 2D dataspace points so that they don't play up... */
+ if (gps->flag & (GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) {
+ td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ;
+ // XXX: matrices may need to be different?
+ }
+
+ /* apply parent transformations */
+ copy_m3_m4(td->smtx, inverse_diff_mat); /* final position */
+ copy_m3_m4(td->mtx, diff_mat); /* display position */
+ copy_m3_m4(td->axismtx, diff_mat); /* axis orientation */
+ }
+ /* Triangulation must be calculated again, so save the stroke for recalc function */
+ td->extra = gps;
+
+ /* save pointer to object */
+ td->ob = obact;
+
+ td++;
+ tail++;
}
}
- /* Triangulation must be calculated again, so save the stroke for recalc function */
- td->extra = gps;
- td++;
- tail++;
+ /* March over these points, and calculate the proportional editing distances */
+ if (is_prop_edit && (head != tail)) {
+ /* XXX: for now, we are similar enough that this works... */
+ calc_distanceCurveVerts(head, tail - 1);
+ }
}
}
-
- /* March over these points, and calculate the proportional editing distances */
- if (is_prop_edit && (head != tail)) {
- /* XXX: for now, we are similar enough that this works... */
- calc_distanceCurveVerts(head, tail - 1);
- }
+ }
+ /* if not multiedit out of loop */
+ if (!is_multiedit) {
+ break;
}
}
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index e32bef72cf6..a2377166dff 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -74,6 +74,7 @@
#include "BKE_armature.h"
#include "BKE_curve.h"
#include "BKE_fcurve.h"
+#include "BKE_gpencil.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -105,6 +106,7 @@
#include "ED_curve.h" /* for curve_editnurbs */
#include "ED_clip.h"
#include "ED_screen.h"
+#include "ED_gpencil.h"
#include "WM_types.h"
#include "WM_api.h"
@@ -379,7 +381,8 @@ static void recalcData_actedit(TransInfo *t)
/* flush transform values back to actual coordinates */
flushTransIntFrameActionData(t);
}
- else {
+
+ if (ac.datatype != ANIMCONT_MASK) {
/* get animdata blocks visible in editor, assuming that these will be the ones where things changed */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
@@ -1116,7 +1119,7 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis
if (t->spacetype == SPACE_VIEW3D) {
View3D *v3d = t->view;
- gpuPushMatrix();
+ GPU_matrix_push();
copy_v3_v3(v3, dir);
mul_v3_fl(v3, v3d->far);
@@ -1132,19 +1135,19 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis
}
UI_make_axis_color(col, col2, axis);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor3ubv(col2);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(pos, v1);
immVertex3fv(pos, v2);
immEnd();
immUnbindProgram();
- gpuPopMatrix();
+ GPU_matrix_pop();
}
}
@@ -1311,7 +1314,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
}
/* GPencil editing context */
- if ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
+ if (GPENCIL_ANY_MODE(gpd)) {
t->options |= CTX_GPENCIL_STROKES;
}
@@ -1350,8 +1353,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
/* turn gizmo off during transform */
if (t->flag & T_MODAL) {
- t->mpr_flag = v3d->mpr_flag;
- v3d->mpr_flag = V3D_GIZMO_HIDE;
+ t->gizmo_flag = v3d->gizmo_flag;
+ v3d->gizmo_flag = V3D_GIZMO_HIDE;
}
if (t->scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) {
@@ -1690,7 +1693,7 @@ void postTrans(bContext *C, TransInfo *t)
View3D *v3d = t->sa->spacedata.first;
/* restore gizmo */
if (t->flag & T_MODAL) {
- v3d->mpr_flag = t->mpr_flag;
+ v3d->gizmo_flag = t->gizmo_flag;
}
}
@@ -1823,6 +1826,21 @@ void calculateCenterCursor(TransInfo *t, float r_center[3])
}
r_center[2] = 0.0f;
}
+ else if (t->options & CTX_GPENCIL_STROKES) {
+ /* move cursor in local space */
+ TransData *td = NULL;
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ float mat[3][3], imat[3][3];
+
+ td = tc->data;
+ Object *ob = td->ob;
+
+ sub_v3_v3v3(r_center, r_center, ob->obmat[3]);
+ copy_m3_m4(mat, ob->obmat);
+ invert_m3_m3(imat, mat);
+ mul_m3_v3(imat, r_center);
+ }
+ }
}
void calculateCenterCursor2D(TransInfo *t, float r_center[2])
diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c
index 995faae8333..ff69c2859fc 100644
--- a/source/blender/editors/transform/transform_gizmo_2d.c
+++ b/source/blender/editors/transform/transform_gizmo_2d.c
@@ -128,16 +128,16 @@ static void gizmo2d_get_axis_color(const int axis_idx, float *r_col, float *r_co
r_col_hi[3] *= alpha_hi;
}
-static GizmoGroup2D *gizmogroup2d_init(wmGizmoGroup *mgroup)
+static GizmoGroup2D *gizmogroup2d_init(wmGizmoGroup *gzgroup)
{
- const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_2d", true);
- const wmGizmoType *wt_cage = WM_gizmotype_find("GIZMO_WT_cage_2d", true);
+ const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_2d", true);
+ const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_2d", true);
GizmoGroup2D *man = MEM_callocN(sizeof(GizmoGroup2D), __func__);
- man->translate_x = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL);
- man->translate_y = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL);
- man->cage = WM_gizmo_new_ptr(wt_cage, mgroup, NULL);
+ man->translate_x = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ man->translate_y = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ man->cage = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL);
RNA_enum_set(man->cage->ptr, "transform",
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE |
@@ -197,11 +197,11 @@ static int gizmo2d_modal(
return OPERATOR_RUNNING_MODAL;
}
-void ED_widgetgroup_gizmo2d_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+void ED_widgetgroup_gizmo2d_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
wmOperatorType *ot_translate = WM_operatortype_find("TRANSFORM_OT_translate", true);
- GizmoGroup2D *man = gizmogroup2d_init(mgroup);
- mgroup->customdata = man;
+ GizmoGroup2D *man = gizmogroup2d_init(gzgroup);
+ gzgroup->customdata = man;
MAN2D_ITER_AXES_BEGIN(axis, axis_idx)
{
@@ -271,9 +271,9 @@ void ED_widgetgroup_gizmo2d_setup(const bContext *UNUSED(C), wmGizmoGroup *mgrou
}
}
-void ED_widgetgroup_gizmo2d_refresh(const bContext *C, wmGizmoGroup *mgroup)
+void ED_widgetgroup_gizmo2d_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- GizmoGroup2D *man = mgroup->customdata;
+ GizmoGroup2D *man = gzgroup->customdata;
float origin[3];
gizmo2d_calc_bounds(C, origin, man->min, man->max);
copy_v2_v2(man->origin, origin);
@@ -321,10 +321,10 @@ void ED_widgetgroup_gizmo2d_refresh(const bContext *C, wmGizmoGroup *mgroup)
}
}
-void ED_widgetgroup_gizmo2d_draw_prepare(const bContext *C, wmGizmoGroup *mgroup)
+void ED_widgetgroup_gizmo2d_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
ARegion *ar = CTX_wm_region(C);
- GizmoGroup2D *man = mgroup->customdata;
+ GizmoGroup2D *man = gzgroup->customdata;
float origin[3] = {UNPACK2(man->origin), 0.0f};
float origin_aa[3] = {UNPACK2(man->origin), 0.0f};
@@ -346,7 +346,7 @@ void ED_widgetgroup_gizmo2d_draw_prepare(const bContext *C, wmGizmoGroup *mgroup
* - Called on every redraw, better to do a more simple poll and check for selection in _refresh
* - UV editing only, could be expanded for other things.
*/
-bool ED_widgetgroup_gizmo2d_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt))
+bool ED_widgetgroup_gizmo2d_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
if ((U.gizmo_flag & USER_GIZMO_DRAW) == 0) {
return false;
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 7d608c433c3..5fe7bbbf45e 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -107,7 +107,7 @@
#define MAN_SCALE_C (MAN_SCALE_X | MAN_SCALE_Y | MAN_SCALE_Z)
/* threshold for testing view aligned gizmo axis */
-struct {
+static struct {
float min, max;
} g_tw_axis_range[2] = {
/* Regular range */
@@ -148,7 +148,9 @@ enum {
#define MAN_AXIS_RANGE_SCALE_START MAN_AXIS_SCALE_X
#define MAN_AXIS_RANGE_SCALE_END (MAN_AXIS_SCALE_ZX + 1)
- MAN_AXIS_LAST = MAN_AXIS_RANGE_SCALE_END,
+ MAN_AXIS_APRON_C,
+
+ MAN_AXIS_LAST = MAN_AXIS_APRON_C + 1,
};
/* axis types */
@@ -162,6 +164,7 @@ enum {
typedef struct GizmoGroup {
bool all_hidden;
int twtype;
+ int axis_type_default;
/* Users may change the twtype, detect changes to re-setup gizmo options. */
int twtype_init;
@@ -193,7 +196,7 @@ static wmGizmo *gizmo_get_axis_from_index(const GizmoGroup *man, const short axi
return man->gizmos[axis_idx];
}
-static short gizmo_get_axis_type(const int axis_idx)
+static short gizmo_get_axis_type(const int axis_idx, const int axis_type_default)
{
if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
return MAN_AXES_TRANSLATE;
@@ -204,6 +207,9 @@ static short gizmo_get_axis_type(const int axis_idx)
if (axis_idx >= MAN_AXIS_RANGE_SCALE_START && axis_idx < MAN_AXIS_RANGE_SCALE_END) {
return MAN_AXES_SCALE;
}
+ if (axis_idx == MAN_AXIS_APRON_C) {
+ return axis_type_default;
+ }
BLI_assert(0);
return -1;
}
@@ -326,6 +332,8 @@ static bool gizmo_is_axis_visible(
rv3d->twdrawflag & MAN_SCALE_X &&
(twtype & SCE_MANIP_TRANSLATE) == 0 &&
(twtype & SCE_MANIP_ROTATE) == 0);
+ case MAN_AXIS_APRON_C:
+ return true;
}
return false;
}
@@ -604,6 +612,7 @@ int ED_transform_calc_gizmo_stats(
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obedit = CTX_data_edit_object(C);
View3D *v3d = sa->spacedata.first;
@@ -611,7 +620,7 @@ int ED_transform_calc_gizmo_stats(
Base *base;
Object *ob = OBACT(view_layer);
bGPdata *gpd = CTX_data_gpencil_data(C);
- const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
+ const bool is_gp_edit = GPENCIL_ANY_MODE(gpd);
int a, totsel = 0;
const int pivot_point = scene->toolsettings->transform_pivot_point;
@@ -728,10 +737,8 @@ int ED_transform_calc_gizmo_stats(
/* only editable and visible layers are considered */
if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
- /* calculate difference matrix if parent object */
- if (gpl->parent != NULL) {
- ED_gpencil_parent_location(gpl, diff_mat);
- }
+ /* calculate difference matrix */
+ ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, diff_mat);
for (bGPDstroke *gps = gpl->actframe->strokes.first; gps; gps = gps->next) {
/* skip strokes that are invalid for current view */
@@ -1137,13 +1144,13 @@ static void gizmo_line_range(const int twtype, const short axis_type, float *r_s
}
static void gizmo_xform_message_subscribe(
- wmGizmoGroup *mgroup, struct wmMsgBus *mbus,
+ wmGizmoGroup *gzgroup, struct wmMsgBus *mbus,
Scene *scene, bScreen *UNUSED(screen), ScrArea *UNUSED(sa), ARegion *ar, const void *type_fn)
{
/* Subscribe to view properties */
- wmMsgSubscribeValue msg_sub_value_mpr_tag_refresh = {
+ wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
.owner = ar,
- .user_data = mgroup->parent_mmap,
+ .user_data = gzgroup->parent_gzmap,
.notify = WM_gizmo_do_msg_notify_tag_refresh,
};
@@ -1159,7 +1166,7 @@ static void gizmo_xform_message_subscribe(
};
for (int i = 0; i < ARRAY_SIZE(props); i++) {
if (props[i]) {
- WM_msg_subscribe_rna(mbus, &scene_ptr, props[i], &msg_sub_value_mpr_tag_refresh, __func__);
+ WM_msg_subscribe_rna(mbus, &scene_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
}
}
}
@@ -1167,25 +1174,27 @@ static void gizmo_xform_message_subscribe(
PointerRNA toolsettings_ptr;
RNA_pointer_create(&scene->id, &RNA_ToolSettings, scene->toolsettings, &toolsettings_ptr);
- if (type_fn == TRANSFORM_WGT_gizmo) {
+ if (type_fn == TRANSFORM_GGT_gizmo) {
extern PropertyRNA rna_ToolSettings_transform_pivot_point;
extern PropertyRNA rna_ToolSettings_use_gizmo_mode;
+ extern PropertyRNA rna_ToolSettings_use_gizmo_apron;
const PropertyRNA *props[] = {
&rna_ToolSettings_transform_pivot_point,
&rna_ToolSettings_use_gizmo_mode,
+ &rna_ToolSettings_use_gizmo_apron,
};
for (int i = 0; i < ARRAY_SIZE(props); i++) {
- WM_msg_subscribe_rna(mbus, &toolsettings_ptr, props[i], &msg_sub_value_mpr_tag_refresh, __func__);
+ WM_msg_subscribe_rna(mbus, &toolsettings_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
}
}
- else if (type_fn == VIEW3D_WGT_xform_cage) {
+ else if (type_fn == VIEW3D_GGT_xform_cage) {
/* pass */
}
else {
BLI_assert(0);
}
- WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_mpr_tag_refresh);
+ WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_gz_tag_refresh);
}
/** \} */
@@ -1195,26 +1204,32 @@ static void gizmo_xform_message_subscribe(
/** \name Transform Gizmo
* \{ */
-static GizmoGroup *gizmogroup_init(wmGizmoGroup *mgroup)
+static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup)
{
GizmoGroup *man;
man = MEM_callocN(sizeof(GizmoGroup), "gizmo_data");
- const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_3d", true);
- const wmGizmoType *wt_dial = WM_gizmotype_find("GIZMO_WT_dial_3d", true);
- const wmGizmoType *wt_prim = WM_gizmotype_find("GIZMO_WT_primitive_3d", true);
+ const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
+ const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
+ const wmGizmoType *gzt_prim = WM_gizmotype_find("GIZMO_GT_primitive_3d", true);
+
+ /* Fallback action. */
+ {
+ const wmGizmoType *gzt_mask = WM_gizmotype_find("GIZMO_GT_blank_3d", true);
+ man->gizmos[MAN_AXIS_APRON_C] = WM_gizmo_new_ptr(gzt_mask, gzgroup, NULL);
+ }
#define GIZMO_NEW_ARROW(v, draw_style) { \
- man->gizmos[v] = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL); \
+ man->gizmos[v] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); \
RNA_enum_set(man->gizmos[v]->ptr, "draw_style", draw_style); \
} ((void)0)
#define GIZMO_NEW_DIAL(v, draw_options) { \
- man->gizmos[v] = WM_gizmo_new_ptr(wt_dial, mgroup, NULL); \
+ man->gizmos[v] = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); \
RNA_enum_set(man->gizmos[v]->ptr, "draw_options", draw_options); \
} ((void)0)
#define GIZMO_NEW_PRIM(v, draw_style) { \
- man->gizmos[v] = WM_gizmo_new_ptr(wt_prim, mgroup, NULL); \
+ man->gizmos[v] = WM_gizmo_new_ptr(gzt_prim, gzgroup, NULL); \
RNA_enum_set(man->gizmos[v]->ptr, "draw_style", draw_style); \
} ((void)0)
@@ -1286,15 +1301,29 @@ static int gizmo_modal(
return OPERATOR_RUNNING_MODAL;
}
-static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *mgroup)
+static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup)
{
struct {
wmOperatorType *translate, *rotate, *trackball, *resize;
} ot_store = {NULL};
- GizmoGroup *man = mgroup->customdata;
+ GizmoGroup *man = gzgroup->customdata;
+
+ if (man->twtype & SCE_MANIP_TRANSLATE) {
+ man->axis_type_default = MAN_AXES_TRANSLATE;
+ }
+ else if (man->twtype & SCE_MANIP_ROTATE) {
+ man->axis_type_default = MAN_AXES_ROTATE;
+ }
+ else if (man->twtype & SCE_MANIP_SCALE) {
+ man->axis_type_default = MAN_AXES_SCALE;
+ }
+ else {
+ man->axis_type_default = 0;
+ }
+
MAN_ITER_AXES_BEGIN(axis, axis_idx)
{
- const short axis_type = gizmo_get_axis_type(axis_idx);
+ const short axis_type = gizmo_get_axis_type(axis_idx, man->axis_type_default);
bool constraint_axis[3] = {1, 0, 0};
PointerRNA *ptr;
@@ -1357,6 +1386,9 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *mgroup)
WM_gizmo_set_scale(axis, 0.2f);
}
break;
+ case MAN_AXIS_APRON_C:
+ WM_gizmo_set_scale(axis, 1.2f);
+ break;
}
switch (axis_type) {
@@ -1406,11 +1438,11 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *mgroup)
MAN_ITER_AXES_END;
}
-static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
- GizmoGroup *man = gizmogroup_init(mgroup);
+ GizmoGroup *man = gizmogroup_init(gzgroup);
- mgroup->customdata = man;
+ gzgroup->customdata = man;
{
man->twtype = 0;
@@ -1436,12 +1468,12 @@ static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *mgroup)
}
/* *** set properties for axes *** */
- gizmogroup_init_properties_from_twtype(mgroup);
+ gizmogroup_init_properties_from_twtype(gzgroup);
}
-static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- GizmoGroup *man = mgroup->customdata;
+ GizmoGroup *man = gzgroup->customdata;
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
View3D *v3d = sa->spacedata.first;
@@ -1453,7 +1485,7 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *mgroup)
man->twtype = scene->toolsettings->gizmo_flag & man->twtype_init;
if (man->twtype != man->twtype_prev) {
man->twtype_prev = man->twtype;
- gizmogroup_init_properties_from_twtype(mgroup);
+ gizmogroup_init_properties_from_twtype(gzgroup);
}
}
@@ -1473,7 +1505,7 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *mgroup)
MAN_ITER_AXES_BEGIN(axis, axis_idx)
{
- const short axis_type = gizmo_get_axis_type(axis_idx);
+ const short axis_type = gizmo_get_axis_type(axis_idx, man->axis_type_default);
const int aidx_norm = gizmo_orientation_axis(axis_idx, NULL);
WM_gizmo_set_matrix_location(axis, rv3d->twmat[3]);
@@ -1527,18 +1559,19 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *mgroup)
}
static void WIDGETGROUP_gizmo_message_subscribe(
- const bContext *C, wmGizmoGroup *mgroup, struct wmMsgBus *mbus)
+ const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
{
Scene *scene = CTX_data_scene(C);
bScreen *screen = CTX_wm_screen(C);
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
- gizmo_xform_message_subscribe(mgroup, mbus, scene, screen, sa, ar, TRANSFORM_WGT_gizmo);
+ gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, sa, ar, TRANSFORM_GGT_gizmo);
}
-static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- GizmoGroup *man = mgroup->customdata;
+ const Scene *scene = CTX_data_scene(C);
+ GizmoGroup *man = gzgroup->customdata;
// ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
// View3D *v3d = sa->spacedata.first;
@@ -1561,9 +1594,13 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *mgro
MAN_ITER_AXES_BEGIN(axis, axis_idx)
{
- const short axis_type = gizmo_get_axis_type(axis_idx);
+ const short axis_type = gizmo_get_axis_type(axis_idx, man->axis_type_default);
/* XXX maybe unset _HIDDEN flag on redraw? */
- if (gizmo_is_axis_visible(rv3d, man->twtype, idot, axis_type, axis_idx)) {
+
+ if (axis_idx == MAN_AXIS_APRON_C) {
+ WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, (scene->toolsettings->gizmo_flag & SCE_MANIP_DISABLE_APRON) != 0);
+ }
+ else if (gizmo_is_axis_visible(rv3d, man->twtype, idot, axis_type, axis_idx)) {
WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, false);
}
else {
@@ -1581,6 +1618,7 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *mgro
case MAN_AXIS_ROT_C:
case MAN_AXIS_SCALE_C:
case MAN_AXIS_ROT_T:
+ case MAN_AXIS_APRON_C:
WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->viewinv[2]);
break;
}
@@ -1588,39 +1626,39 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *mgro
MAN_ITER_AXES_END;
}
-static bool WIDGETGROUP_gizmo_poll(const struct bContext *C, struct wmGizmoGroupType *wgt)
+static bool WIDGETGROUP_gizmo_poll(const struct bContext *C, struct wmGizmoGroupType *gzgt)
{
/* it's a given we only use this in 3D view */
bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C);
if ((tref_rt == NULL) ||
- !STREQ(wgt->idname, tref_rt->gizmo_group))
+ !STREQ(gzgt->idname, tref_rt->gizmo_group))
{
- WM_gizmo_group_type_unlink_delayed_ptr(wgt);
+ WM_gizmo_group_type_unlink_delayed_ptr(gzgt);
return false;
}
View3D *v3d = CTX_wm_view3d(C);
- if (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
return false;
}
return true;
}
-void TRANSFORM_WGT_gizmo(wmGizmoGroupType *wgt)
+void TRANSFORM_GGT_gizmo(wmGizmoGroupType *gzgt)
{
- wgt->name = "Transform Gizmo";
- wgt->idname = "TRANSFORM_WGT_gizmo";
+ gzgt->name = "Transform Gizmo";
+ gzgt->idname = "TRANSFORM_GGT_gizmo";
- wgt->flag |= WM_GIZMOGROUPTYPE_3D;
+ gzgt->flag |= WM_GIZMOGROUPTYPE_3D;
- wgt->mmap_params.spaceid = SPACE_VIEW3D;
- wgt->mmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- wgt->poll = WIDGETGROUP_gizmo_poll;
- wgt->setup = WIDGETGROUP_gizmo_setup;
- wgt->refresh = WIDGETGROUP_gizmo_refresh;
- wgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe;
- wgt->draw_prepare = WIDGETGROUP_gizmo_draw_prepare;
+ gzgt->poll = WIDGETGROUP_gizmo_poll;
+ gzgt->setup = WIDGETGROUP_gizmo_setup;
+ gzgt->refresh = WIDGETGROUP_gizmo_refresh;
+ gzgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe;
+ gzgt->draw_prepare = WIDGETGROUP_gizmo_draw_prepare;
}
/** \} */
@@ -1634,31 +1672,31 @@ struct XFormCageWidgetGroup {
wmGizmo *gizmo;
};
-static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmGizmoGroupType *wgt)
+static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C);
- if (!STREQ(wgt->idname, tref_rt->gizmo_group)) {
- WM_gizmo_group_type_unlink_delayed_ptr(wgt);
+ if (!STREQ(gzgt->idname, tref_rt->gizmo_group)) {
+ WM_gizmo_group_type_unlink_delayed_ptr(gzgt);
return false;
}
return true;
}
-static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup)
+static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- struct XFormCageWidgetGroup *xmgroup = MEM_mallocN(sizeof(struct XFormCageWidgetGroup), __func__);
- const wmGizmoType *wt_cage = WM_gizmotype_find("GIZMO_WT_cage_3d", true);
- xmgroup->gizmo = WM_gizmo_new_ptr(wt_cage, mgroup, NULL);
- wmGizmo *mpr = xmgroup->gizmo;
+ struct XFormCageWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormCageWidgetGroup), __func__);
+ const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true);
+ xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL);
+ wmGizmo *gz = xgzgroup->gizmo;
- RNA_enum_set(mpr->ptr, "transform",
+ RNA_enum_set(gz->ptr, "transform",
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE |
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE);
- mpr->color[0] = 1;
- mpr->color_hi[0] = 1;
+ gz->color[0] = 1;
+ gz->color_hi[0] = 1;
- mgroup->customdata = xmgroup;
+ gzgroup->customdata = xgzgroup;
{
wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
@@ -1673,7 +1711,7 @@ static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup
for (int y = 0; y < 3; y++) {
for (int z = 0; z < 3; z++) {
bool constraint[3] = {x != 1, y != 1, z != 1};
- ptr = WM_gizmo_operator_set(mpr, i, ot_resize, NULL);
+ ptr = WM_gizmo_operator_set(gz, i, ot_resize, NULL);
if (prop_release_confirm == NULL) {
prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm");
prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
@@ -1687,15 +1725,15 @@ static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup
}
}
-static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = ar->regiondata;
- struct XFormCageWidgetGroup *xmgroup = mgroup->customdata;
- wmGizmo *mpr = xmgroup->gizmo;
+ struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata;
+ wmGizmo *gz = xgzgroup->gizmo;
struct TransformBounds tbounds;
@@ -1705,22 +1743,22 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *mgro
}, &tbounds) == 0) ||
equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max))
{
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
}
else {
gizmo_prepare_mat(C, v3d, rv3d, &tbounds);
- WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false);
- WM_gizmo_set_flag(mpr, WM_GIZMO_GRAB_CURSOR, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
+ WM_gizmo_set_flag(gz, WM_GIZMO_GRAB_CURSOR, true);
float dims[3];
sub_v3_v3v3(dims, rv3d->tw_axis_max, rv3d->tw_axis_min);
- RNA_float_set_array(mpr->ptr, "dimensions", dims);
+ RNA_float_set_array(gz->ptr, "dimensions", dims);
mul_v3_fl(dims, 0.5f);
- copy_m4_m3(mpr->matrix_offset, rv3d->tw_axis_matrix);
- mid_v3_v3v3(mpr->matrix_offset[3], rv3d->tw_axis_max, rv3d->tw_axis_min);
- mul_m3_v3(rv3d->tw_axis_matrix, mpr->matrix_offset[3]);
+ copy_m4_m3(gz->matrix_offset, rv3d->tw_axis_matrix);
+ mid_v3_v3v3(gz->matrix_offset[3], rv3d->tw_axis_max, rv3d->tw_axis_min);
+ mul_m3_v3(rv3d->tw_axis_matrix, gz->matrix_offset[3]);
PropertyRNA *prop_center_override = NULL;
float center[3];
@@ -1732,11 +1770,11 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *mgro
center[1] = (float)(1 - y) * dims[1];
for (int z = 0; z < 3; z++) {
center[2] = (float)(1 - z) * dims[2];
- struct wmGizmoOpElem *mpop = WM_gizmo_operator_get(mpr, i);
+ struct wmGizmoOpElem *mpop = WM_gizmo_operator_get(gz, i);
if (prop_center_override == NULL) {
prop_center_override = RNA_struct_find_property(&mpop->ptr, "center_override");
}
- mul_v3_m4v3(center_global, mpr->matrix_offset, center);
+ mul_v3_m4v3(center_global, gz->matrix_offset, center);
RNA_property_float_set_array(&mpop->ptr, prop_center_override, center_global);
i++;
}
@@ -1746,45 +1784,45 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *mgro
}
static void WIDGETGROUP_xform_cage_message_subscribe(
- const bContext *C, wmGizmoGroup *mgroup, struct wmMsgBus *mbus)
+ const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
{
Scene *scene = CTX_data_scene(C);
bScreen *screen = CTX_wm_screen(C);
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
- gizmo_xform_message_subscribe(mgroup, mbus, scene, screen, sa, ar, VIEW3D_WGT_xform_cage);
+ gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, sa, ar, VIEW3D_GGT_xform_cage);
}
-static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *mgroup)
+static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct XFormCageWidgetGroup *xmgroup = mgroup->customdata;
- wmGizmo *mpr = xmgroup->gizmo;
+ struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata;
+ wmGizmo *gz = xgzgroup->gizmo;
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
if (ob && ob->mode & OB_MODE_EDIT) {
- copy_m4_m4(mpr->matrix_space, ob->obmat);
+ copy_m4_m4(gz->matrix_space, ob->obmat);
}
else {
- unit_m4(mpr->matrix_space);
+ unit_m4(gz->matrix_space);
}
}
-void VIEW3D_WGT_xform_cage(wmGizmoGroupType *wgt)
+void VIEW3D_GGT_xform_cage(wmGizmoGroupType *gzgt)
{
- wgt->name = "Transform Cage";
- wgt->idname = "VIEW3D_WGT_xform_cage";
+ gzgt->name = "Transform Cage";
+ gzgt->idname = "VIEW3D_GGT_xform_cage";
- wgt->flag |= WM_GIZMOGROUPTYPE_3D;
+ gzgt->flag |= WM_GIZMOGROUPTYPE_3D;
- wgt->mmap_params.spaceid = SPACE_VIEW3D;
- wgt->mmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- wgt->poll = WIDGETGROUP_xform_cage_poll;
- wgt->setup = WIDGETGROUP_xform_cage_setup;
- wgt->refresh = WIDGETGROUP_xform_cage_refresh;
- wgt->message_subscribe = WIDGETGROUP_xform_cage_message_subscribe;
- wgt->draw_prepare = WIDGETGROUP_xform_cage_draw_prepare;
+ gzgt->poll = WIDGETGROUP_xform_cage_poll;
+ gzgt->setup = WIDGETGROUP_xform_cage_setup;
+ gzgt->refresh = WIDGETGROUP_xform_cage_refresh;
+ gzgt->message_subscribe = WIDGETGROUP_xform_cage_message_subscribe;
+ gzgt->draw_prepare = WIDGETGROUP_xform_cage_draw_prepare;
}
/** \} */
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index c9a97c8530c..1f1cc646f20 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -82,6 +82,7 @@ static const char OP_VERT_SLIDE[] = "TRANSFORM_OT_vert_slide";
static const char OP_EDGE_CREASE[] = "TRANSFORM_OT_edge_crease";
static const char OP_EDGE_BWEIGHT[] = "TRANSFORM_OT_edge_bevelweight";
static const char OP_SEQ_SLIDE[] = "TRANSFORM_OT_seq_slide";
+static const char OP_NORMAL_ROTATION[] = "TRANSFORM_OT_rotate_normal";
static void TRANSFORM_OT_translate(struct wmOperatorType *ot);
static void TRANSFORM_OT_rotate(struct wmOperatorType *ot);
@@ -100,6 +101,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot);
static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot);
static void TRANSFORM_OT_edge_bevelweight(struct wmOperatorType *ot);
static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot);
+static void TRANSFORM_OT_rotate_normal(struct wmOperatorType *ot);
static TransformModeItem transform_modes[] =
{
@@ -120,6 +122,7 @@ static TransformModeItem transform_modes[] =
{OP_EDGE_CREASE, TFM_CREASE, TRANSFORM_OT_edge_crease},
{OP_EDGE_BWEIGHT, TFM_BWEIGHT, TRANSFORM_OT_edge_bevelweight},
{OP_SEQ_SLIDE, TFM_SEQ_SLIDE, TRANSFORM_OT_seq_slide},
+ {OP_NORMAL_ROTATION, TFM_NORMAL_ROTATION, TRANSFORM_OT_rotate_normal},
{NULL, 0}
};
@@ -507,6 +510,36 @@ static int transform_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
}
+static bool transform_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
+{
+ const char *prop_id = RNA_property_identifier(prop);
+
+ /* Orientation/Constraints. */
+ {
+ /* Hide orientation axis if no constraints are set, since it wont be used. */
+ PropertyRNA *prop_con = RNA_struct_find_property(op->ptr, "constraint_axis");
+ if (prop_con && !RNA_property_is_set(op->ptr, prop_con)) {
+ if (STRPREFIX(prop_id, "constraint")) {
+ return false;
+ }
+ }
+ }
+
+ /* Proportional Editing. */
+ {
+ PropertyRNA *prop_pet = RNA_struct_find_property(op->ptr, "proportional");
+ if (prop_pet && (prop_pet != prop) &&
+ (RNA_property_enum_get(op->ptr, prop_pet) == PROP_EDIT_OFF))
+ {
+ if (STRPREFIX(prop_id, "proportional")) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
void Transform_Properties(struct wmOperatorType *ot, int flags)
{
PropertyRNA *prop;
@@ -615,6 +648,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
@@ -640,6 +674,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
@@ -673,6 +708,7 @@ static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = skin_resize_poll;
+ ot->poll_property = transform_poll_property;
RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
@@ -695,6 +731,7 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
/* Maybe we could use float_vector_xyz here too? */
RNA_def_float_rotation(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
@@ -718,6 +755,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
@@ -744,6 +782,7 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_editcurve_3d;
+ ot->poll_property = transform_poll_property;
RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
@@ -766,6 +805,7 @@ static void TRANSFORM_OT_bend(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_region_view3d_active;
+ ot->poll_property = transform_poll_property;
RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
@@ -788,6 +828,7 @@ static void TRANSFORM_OT_shear(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
@@ -811,6 +852,7 @@ static void TRANSFORM_OT_push_pull(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Distance", "", -FLT_MAX, FLT_MAX);
@@ -833,6 +875,7 @@ static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_editmesh;
+ ot->poll_property = transform_poll_property;
RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
@@ -858,6 +901,7 @@ static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1);
@@ -880,6 +924,7 @@ static void TRANSFORM_OT_mirror(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_GPENCIL_EDIT | P_CENTER);
}
@@ -900,6 +945,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_editmesh_region_view3d;
+ ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f);
@@ -932,6 +978,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_editmesh_region_view3d;
+ ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f);
RNA_def_boolean(ot->srna, "use_even", false, "Even",
@@ -961,6 +1008,7 @@ static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_editmesh;
+ ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
@@ -1034,6 +1082,27 @@ static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot)
Transform_Properties(ot, P_SNAP);
}
+static void TRANSFORM_OT_rotate_normal(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Normal Rotate";
+ ot->description = "Rotate split normal of selected items";
+ ot->idname = OP_NORMAL_ROTATION;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_editmesh_auto_smooth;
+
+ RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
+
+ Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_MIRROR);
+}
+
+
static void TRANSFORM_OT_transform(struct wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -1050,6 +1119,7 @@ static void TRANSFORM_OT_transform(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
prop = RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index dc922b5c9ba..54253e36351 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -165,7 +165,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
invert_m4_m4(imat, rv3d->viewmat);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -190,7 +190,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
if (usingSnappingNormal(t) && validSnappingNormal(t)) {
immUniformColor4ubv(activeCol);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex3f(pos, t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]);
immVertex3f(pos, t->tsnap.snapPoint[0] + t->tsnap.snapNormal[0],
t->tsnap.snapPoint[1] + t->tsnap.snapNormal[1],
@@ -219,7 +219,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
GPU_blend(true);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1462,7 +1462,7 @@ void snapSequenceBounds(TransInfo *t, const int mval[2])
float xmouse, ymouse;
int frame;
int mframe;
- TransSeq *ts = t->custom.type.data;
+ TransSeq *ts = TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
/* reuse increment, strictly speaking could be another snap mode, but leave as is */
if (!(t->modifiers & MOD_SNAP_INVERT))
return;
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index e19320fa220..6dfcfe11af2 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -111,6 +111,10 @@ typedef struct SnapObjectData_EditMesh {
SnapObjectData sd;
BVHTreeFromEditMesh *bvh_trees[3];
+ /* It's like a boundbox. It is tested first to avoid
+ * to create a bvhtree for all the edited objects. */
+ float min[3], max[3];
+
} SnapObjectData_EditMesh;
struct SnapObjectContext {
@@ -156,6 +160,39 @@ struct SnapObjectContext {
typedef void(*IterSnapObjsCallback)(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data);
+static void min_max_from_bmesh(
+ BMesh *bm, float r_min[3], float r_max[3])
+{
+ BMIter iter;
+ BMVert *eve;
+
+ INIT_MINMAX(r_min, r_max);
+ BM_ITER_MESH(eve, &iter, bm, BM_VERTS_OF_MESH) {
+ minmax_v3v3_v3(r_min, r_max, eve->co);
+ }
+}
+
+static SnapObjectData_Mesh *snap_object_data_mesh_create(SnapObjectContext *sctx)
+{
+ SnapObjectData_Mesh *sod = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ sod->sd.type = SNAP_MESH;
+ /* start assuming that it has each of these element types */
+ sod->has_looptris = true;
+ sod->has_loose_edge = true;
+ sod->has_loose_vert = true;
+
+ return sod;
+}
+
+static SnapObjectData_EditMesh *snap_object_data_editmesh_create(SnapObjectContext *sctx, BMesh *bm)
+{
+ SnapObjectData_EditMesh *sod = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ sod->sd.type = SNAP_EDIT_MESH;
+ min_max_from_bmesh(bm, sod->min, sod->max);
+
+ return sod;
+}
+
/**
* Walks through all objects in the scene to create the list of objets to snap.
*
@@ -169,9 +206,9 @@ static void iter_snap_objects(
IterSnapObjsCallback sob_callback,
void *data)
{
- ViewLayer *view_layer = DEG_get_evaluated_view_layer(sctx->depsgraph);
- Object *obedit = params->use_object_edit_cage ? OBEDIT_FROM_VIEW_LAYER(view_layer) : NULL;
+ ViewLayer *view_layer = DEG_get_input_view_layer(sctx->depsgraph);
const eSnapSelect snap_select = params->snap_select;
+ const bool use_object_edit_cage = params->use_object_edit_cage;
Base *base_act = view_layer->basact;
for (Base *base = view_layer->object_bases.first; base != NULL; base = base->next) {
@@ -179,20 +216,17 @@ static void iter_snap_objects(
!((snap_select == SNAP_NOT_SELECTED && ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL))) ||
(snap_select == SNAP_NOT_ACTIVE && base == base_act)))
{
- bool use_obedit;
- Object *obj = base->object;
- if (obj->transflag & OB_DUPLI) {
+ Object *obj_eval = DEG_get_evaluated_object(sctx->depsgraph, base->object);
+ if (obj_eval->transflag & OB_DUPLI) {
DupliObject *dupli_ob;
- ListBase *lb = object_duplilist(sctx->depsgraph, sctx->scene, obj);
+ ListBase *lb = object_duplilist(sctx->depsgraph, sctx->scene, obj_eval);
for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
- use_obedit = obedit && dupli_ob->ob->data == obedit->data;
- sob_callback(sctx, use_obedit, use_obedit ? obedit : dupli_ob->ob, dupli_ob->mat, data);
+ sob_callback(sctx, use_object_edit_cage, dupli_ob->ob, dupli_ob->mat, data);
}
free_object_duplilist(lb);
}
- use_obedit = obedit && obj->data == obedit->data;
- sob_callback(sctx, use_obedit, use_obedit ? obedit : obj, obj->obmat, data);
+ sob_callback(sctx, use_object_edit_cage, obj_eval, obj_eval->obmat, data);
}
}
}
@@ -372,13 +406,12 @@ static bool raycastMesh(
sod = *sod_p;
}
else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
- sod->sd.type = SNAP_MESH;
+ sod = *sod_p = snap_object_data_mesh_create(sctx);
}
BVHTreeFromMesh *treedata = &sod->treedata;
- /* The tree is owned by the DM and may have been freed since we last used. */
+ /* The tree is owned by the Mesh and may have been freed since we last used. */
if (treedata->tree) {
BLI_assert(treedata->cached);
if (!bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) {
@@ -502,14 +535,30 @@ static bool raycastEditMesh(
SnapObjectData_EditMesh *sod = NULL;
BVHTreeFromEditMesh *treedata = NULL;
+ Object *em_ob = em->ob;
+
+ BLI_assert(em_ob->data == BKE_object_get_pre_modified_mesh(ob));
void **sod_p;
- if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
+ /* Use `em->ob` as the key in ghash since the editmesh is used
+ * to create bvhtree and is the same for each linked object. */
+ if (BLI_ghash_ensure_p(sctx->cache.object_map, em_ob, &sod_p)) {
sod = *sod_p;
}
else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
- sod->sd.type = SNAP_EDIT_MESH;
+ sod = *sod_p = snap_object_data_editmesh_create(sctx, em->bm);
+ }
+
+ {
+ float min[3], max[3];
+ mul_v3_m4v3(min, obmat, sod->min);
+ mul_v3_m4v3(max, obmat, sod->max);
+
+ if (!isect_ray_aabb_v3_simple(
+ ray_start, ray_dir, min, max, NULL, NULL))
+ {
+ return retval;
+ }
}
if (sod->bvh_trees[2] == NULL) {
@@ -517,7 +566,17 @@ static bool raycastEditMesh(
}
treedata = sod->bvh_trees[2];
+ BVHCache *em_bvh_cache = ((Mesh *)em_ob->data)->runtime.bvh_cache;
+
+ if (sctx->callbacks.edit_mesh.test_face_fn == NULL) {
+ /* The tree is owned by the Mesh and may have been freed since we last used! */
+ if (!bvhcache_has_tree(em_bvh_cache, treedata->tree)) {
+ free_bvhtree_from_editmesh(treedata);
+ }
+ }
+
if (treedata->tree == NULL) {
+ BVHCache **bvh_cache = NULL;
BLI_bitmap *elem_mask = NULL;
int looptri_num_active = -1;
@@ -527,7 +586,15 @@ static bool raycastEditMesh(
em->bm, elem_mask,
sctx->callbacks.edit_mesh.test_face_fn, sctx->callbacks.edit_mesh.user_data);
}
- bvhtree_from_editmesh_looptri_ex(treedata, em, elem_mask, looptri_num_active, 0.0f, 4, 6, NULL);
+ else {
+ /* Only cache if bvhtree is created without a mask.
+ * This helps keep a standardized bvhtree in cache. */
+ bvh_cache = &em_bvh_cache;
+ }
+
+ bvhtree_from_editmesh_looptri_ex(
+ treedata, em, elem_mask, looptri_num_active,
+ 0.0f, 4, 6, bvh_cache);
if (elem_mask) {
MEM_freeN(elem_mask);
@@ -669,7 +736,7 @@ static bool raycastObj(
switch (ob->type) {
case OB_MESH:
- if (use_obedit) {
+ if (use_obedit && BKE_object_is_in_editmode(ob)) {
BMEditMesh *em = BKE_editmesh_from_object(ob);
retval = raycastEditMesh(
sctx,
@@ -718,7 +785,7 @@ struct RaycastObjUserData {
bool ret;
};
-static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data)
+static void raycast_obj_cb(SnapObjectContext *sctx, bool use_obedit, Object *ob, float obmat[4][4], void *data)
{
struct RaycastObjUserData *dt = data;
@@ -726,7 +793,7 @@ static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob,
sctx,
dt->ray_start, dt->ray_dir,
ob, obmat, dt->ob_index++,
- is_obedit, dt->use_occlusion_test,
+ use_obedit, dt->use_occlusion_test,
dt->ray_depth,
dt->r_loc, dt->r_no, dt->r_index,
dt->r_ob, dt->r_obmat,
@@ -1118,6 +1185,13 @@ static short snap_mesh_polygon(
};
SnapObjectData *sod = BLI_ghash_lookup(sctx->cache.object_map, ob);
+ if (sod == NULL) {
+ /* The object is in edit mode, and the key used
+ * was the object referenced in BMEditMesh */
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ sod = BLI_ghash_lookup(sctx->cache.object_map, em->ob);
+ }
+
BLI_assert(sod != NULL);
if (sod->type == SNAP_MESH) {
@@ -1335,6 +1409,8 @@ static short snapArmature(
dist_squared_to_projected_aabb_precalc(
&neasrest_precalc, lpmat, snapdata->win_size, snapdata->mval);
+ use_obedit = use_obedit && BKE_object_is_in_editmode(ob);
+
if (use_obedit == false) {
/* Test BoundBox */
BoundBox *bb = BKE_armature_boundbox_get(ob);
@@ -1469,6 +1545,8 @@ static short snapCurve(
dist_squared_to_projected_aabb_precalc(
&neasrest_precalc, lpmat, snapdata->win_size, snapdata->mval);
+ use_obedit = use_obedit && BKE_object_is_in_editmode(ob);
+
if (use_obedit == false) {
/* Test BoundBox */
BoundBox *bb = BKE_curve_boundbox_get(ob);
@@ -1779,12 +1857,7 @@ static short snapMesh(
sod = *sod_p;
}
else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
- sod->sd.type = SNAP_MESH;
- /* start assuming that it has each of these element types */
- sod->has_looptris = true;
- sod->has_loose_edge = true;
- sod->has_loose_vert = true;
+ sod = *sod_p = snap_object_data_mesh_create(sctx);
}
BVHTreeFromMesh *treedata, dummy_treedata;
@@ -1792,7 +1865,7 @@ static short snapMesh(
treedata = &sod->treedata;
bvhtree = sod->bvhtree;
- /* the tree is owned by the DM and may have been freed since we last used! */
+ /* The tree is owned by the Mesh and may have been freed since we last used! */
if ((sod->has_looptris && treedata->tree && !bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) ||
(sod->has_loose_edge && bvhtree[0] && !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[0])) ||
(sod->has_loose_vert && bvhtree[1] && !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[1])))
@@ -1982,21 +2055,57 @@ static short snapEditMesh(
SnapObjectData_EditMesh *sod = NULL;
BVHTreeFromEditMesh *treedata_vert = NULL, *treedata_edge = NULL;
+ Object *em_ob = em->ob;
+
+ BLI_assert(em_ob->data == BKE_object_get_pre_modified_mesh(ob));
+ UNUSED_VARS_NDEBUG(ob);
void **sod_p;
- if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
+ /* Use `em->ob` as the key in ghash since the editmesh is used
+ * to create bvhtree and is the same for each linked object. */
+ if (BLI_ghash_ensure_p(sctx->cache.object_map, em_ob, &sod_p)) {
sod = *sod_p;
}
else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
- sod->sd.type = SNAP_EDIT_MESH;
+ sod = *sod_p = snap_object_data_editmesh_create(sctx, em->bm);
}
+ float dist_px_sq = SQUARE(*dist_px);
+
+ {
+ float min[3], max[3];
+ mul_v3_m4v3(min, obmat, sod->min);
+ mul_v3_m4v3(max, obmat, sod->max);
+
+ /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */
+ struct DistProjectedAABBPrecalc data_precalc;
+ dist_squared_to_projected_aabb_precalc(
+ &data_precalc, snapdata->pmat, snapdata->win_size, snapdata->mval);
+
+ bool dummy[3];
+ float bb_dist_px_sq = dist_squared_to_projected_aabb(
+ &data_precalc, min, max, dummy);
+
+ if (bb_dist_px_sq > dist_px_sq) {
+ return 0;
+ }
+ }
+
+ BVHCache *em_bvh_cache = ((Mesh *)em_ob->data)->runtime.bvh_cache;
+
if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) {
if (sod->bvh_trees[0] == NULL) {
sod->bvh_trees[0] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees));
}
treedata_vert = sod->bvh_trees[0];
+
+ if (sctx->callbacks.edit_mesh.test_vert_fn == NULL) {
+ /* The tree is owned by the Mesh and may have been freed since we last used! */
+ if (!bvhcache_has_tree(em_bvh_cache, treedata_vert->tree)) {
+ free_bvhtree_from_editmesh(treedata_vert);
+ }
+ }
+
if (treedata_vert->tree == NULL) {
BLI_bitmap *verts_mask = NULL;
int verts_num_active = -1;
@@ -2006,9 +2115,13 @@ static short snapEditMesh(
BM_VERTS_OF_MESH, em->bm, verts_mask,
(bool(*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn,
sctx->callbacks.edit_mesh.user_data);
+
+ bvhtree_from_editmesh_verts_ex(treedata_vert, em, verts_mask, verts_num_active, 0.0f, 2, 6);
+ MEM_freeN(verts_mask);
+ }
+ else {
+ bvhtree_from_editmesh_verts(treedata_vert, em, 0.0f, 2, 6, &em_bvh_cache);
}
- bvhtree_from_editmesh_verts_ex(treedata_vert, em, verts_mask, verts_num_active, 0.0f, 2, 6);
- MEM_SAFE_FREE(verts_mask);
}
}
@@ -2017,6 +2130,14 @@ static short snapEditMesh(
sod->bvh_trees[1] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees));
}
treedata_edge = sod->bvh_trees[1];
+
+ if (sctx->callbacks.edit_mesh.test_edge_fn == NULL) {
+ /* The tree is owned by the Mesh and may have been freed since we last used! */
+ if (!bvhcache_has_tree(em_bvh_cache, treedata_edge->tree)) {
+ free_bvhtree_from_editmesh(treedata_edge);
+ }
+ }
+
if (treedata_edge->tree == NULL) {
BLI_bitmap *edges_mask = NULL;
int edges_num_active = -1;
@@ -2027,9 +2148,12 @@ static short snapEditMesh(
(bool(*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_edge_fn,
sctx->callbacks.edit_mesh.user_data);
+ bvhtree_from_editmesh_edges_ex(treedata_edge, em, edges_mask, edges_num_active, 0.0f, 2, 6);
+ MEM_freeN(edges_mask);
+ }
+ else {
+ bvhtree_from_editmesh_edges(treedata_edge, em, 0.0f, 2, 6, &em_bvh_cache);
}
- bvhtree_from_editmesh_edges_ex(treedata_edge, em, edges_mask, edges_num_active, 0.0f, 2, 6);
- MEM_SAFE_FREE(edges_mask);
}
}
@@ -2043,7 +2167,7 @@ static short snapEditMesh(
BVHTreeNearest nearest = {
.index = -1,
- .dist_sq = SQUARE(*dist_px),
+ .dist_sq = dist_px_sq,
};
int last_index = nearest.index;
short elem = SCE_SNAP_MODE_VERTEX;
@@ -2119,7 +2243,7 @@ static short snapObject(
switch (ob->type) {
case OB_MESH:
- if (use_obedit) {
+ if (use_obedit && BKE_object_is_in_editmode(ob)) {
BMEditMesh *em = BKE_editmesh_from_object(ob);
retval = snapEditMesh(
sctx, snapdata, ob, em, obmat,
@@ -2156,7 +2280,12 @@ static short snapObject(
dist_px,
r_loc, r_no, r_index);
break;
-
+ case OB_GPENCIL:
+ retval = snapEmpty(
+ snapdata, ob, obmat,
+ dist_px,
+ r_loc, r_no, r_index);
+ break;
case OB_CAMERA:
retval = snapCamera(
sctx, snapdata, ob, obmat,
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 14592149579..ffe4008f7d6 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -48,12 +48,16 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_layer.h"
#include "BKE_undo_system.h"
+#include "BKE_workspace.h"
+#include "BKE_paint.h"
#include "ED_gpencil.h"
#include "ED_render.h"
+#include "ED_object.h"
#include "ED_screen.h"
#include "ED_undo.h"
@@ -110,6 +114,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
+ ScrArea *sa = CTX_wm_area(C);
/* undo during jobs are running can easily lead to freeing data using by jobs,
* or they can just lead to freezing job in some other cases */
@@ -122,6 +127,12 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
if (ED_gpencil_session_active()) {
return ED_undo_gpencil_step(C, step, undoname);
}
+ if (sa && (sa->spacetype == SPACE_VIEW3D)) {
+ Object *obact = CTX_data_active_object(C);
+ if (obact && (obact->type == OB_GPENCIL)) {
+ ED_gpencil_toggle_brush_cursor(C, false, NULL);
+ }
+ }
UndoStep *step_data_from_name = NULL;
int step_for_callback = step;
@@ -156,6 +167,23 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
else {
BKE_undosys_step_undo_compat_only(wm->undo_stack, C, step);
}
+
+ /* Set special modes for grease pencil */
+ if (sa && (sa->spacetype == SPACE_VIEW3D)) {
+ Object *obact = CTX_data_active_object(C);
+ if (obact && (obact->type == OB_GPENCIL)) {
+ /* set cursor */
+ if (ELEM(obact->mode, OB_MODE_GPENCIL_PAINT, OB_MODE_GPENCIL_SCULPT, OB_MODE_GPENCIL_WEIGHT)) {
+ ED_gpencil_toggle_brush_cursor(C, true, NULL);
+ }
+ else {
+ ED_gpencil_toggle_brush_cursor(C, false, NULL);
+ }
+ /* set workspace mode */
+ Base *basact = CTX_data_active_base(C);
+ ED_object_base_activate(C, basact);
+ }
+ }
}
/* App-Handlers (post). */
@@ -387,6 +415,15 @@ int ED_undo_operator_repeat(bContext *C, wmOperator *op)
}
}
+ if (op->type->flag & OPTYPE_USE_EVAL_DATA) {
+ /* We need to force refresh of depsgraph after undo step,
+ * redoing the operator *may* rely on some valid evaluated data. */
+ Main *bmain = CTX_data_main(C);
+ scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_scene_view_layer_graph_evaluated_ensure(bmain, scene, view_layer);
+ }
+
retval = WM_operator_repeat(C, op);
if ((retval & OPERATOR_FINISHED) == 0) {
if (G.debug & G_DEBUG)
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 65147d53b5d..35a77fcd4c0 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -342,7 +342,7 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info
const float mval_dst[2] = {win->eventstate->x - ar->winrct.xmin,
win->eventstate->y - ar->winrct.ymin};
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -355,7 +355,7 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info
immUniform1f("dash_width", 6.0f);
immUniform1f("dash_factor", 0.5f);
- immBegin(GWN_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
immVertex2fv(shdr_pos, mval_src);
immVertex2fv(shdr_pos, mval_dst);
immEnd();
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index f0d6b5c2a71..616f4eac2ad 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -90,9 +90,9 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
GPU_line_width(1.0f);
- gpuTranslate2fv(cursor);
+ GPU_matrix_translate_2fv(cursor);
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -104,7 +104,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2);
immUniform1f("dash_width", 8.0f);
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
immVertex2f(shdr_pos, -0.05f * x_fac, 0.0f);
immVertex2f(shdr_pos, 0.0f, 0.05f * y_fac);
@@ -123,7 +123,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2);
immUniform1f("dash_width", 2.0f);
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
immVertex2f(shdr_pos, -0.020f * x_fac, 0.0f);
immVertex2f(shdr_pos, -0.1f * x_fac, 0.0f);
@@ -141,7 +141,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
immUnbindProgram();
- gpuTranslate2f(-cursor[0], -cursor[1]);
+ GPU_matrix_translate_2f(-cursor[0], -cursor[1]);
}
static int draw_uvs_face_check(Scene *scene)
@@ -168,7 +168,7 @@ static void draw_uvs_shadow(Object *obedit)
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -229,7 +229,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
}
}
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -241,7 +241,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- immBegin(GWN_PRIM_TRI_FAN, efa->len);
+ immBegin(GPU_PRIM_TRI_FAN, efa->len);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -281,7 +281,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
immUniformColor3fv(col);
/* TODO: use editmesh tessface */
- immBegin(GWN_PRIM_TRI_FAN, efa->len);
+ immBegin(GPU_PRIM_TRI_FAN, efa->len);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -308,9 +308,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
col[3] = 0.5f; /* hard coded alpha, not that nice */
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
@@ -353,7 +353,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
}
/* TODO: use editmesh tessface */
- immBegin(GWN_PRIM_TRI_FAN, efa->len);
+ immBegin(GPU_PRIM_TRI_FAN, efa->len);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
a = fabsf(uvang[i] - ang[i]) / (float)M_PI;
@@ -393,7 +393,7 @@ static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, co
MLoopUV *luv;
/* For more efficiency first transfer the entire buffer to vram. */
- Gwn_Batch *loop_batch = immBeginBatchAtMost(GWN_PRIM_LINE_LOOP, bm->totloop);
+ GPUBatch *loop_batch = immBeginBatchAtMost(GPU_PRIM_LINE_LOOP, bm->totloop);
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
@@ -407,17 +407,17 @@ static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, co
immEnd();
/* Then draw each face contour separately. */
- GWN_batch_program_use_begin(loop_batch);
+ GPU_batch_program_use_begin(loop_batch);
unsigned int index = 0;
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
+ GPU_batch_draw_range_ex(loop_batch, index, efa->len, false);
index += efa->len;
}
- GWN_batch_program_use_end(loop_batch);
- GWN_batch_discard(loop_batch);
+ GPU_batch_program_use_end(loop_batch);
+ GPU_batch_discard(loop_batch);
}
static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly, unsigned int pos)
@@ -425,7 +425,7 @@ static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly, unsigned int pos)
MLoopUV *mloopuv;
int i;
- immBegin(GWN_PRIM_LINE_LOOP, mpoly->totloop);
+ immBegin(GPU_PRIM_LINE_LOOP, mpoly->totloop);
mloopuv = &me->mloopuv[mpoly->loopstart];
for (i = mpoly->totloop; i != 0; i--, mloopuv++) {
@@ -495,7 +495,7 @@ static void draw_uvs_other_mesh(Object *ob, const Image *curimage,
static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *curimage,
const int other_uv_filter)
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -536,7 +536,7 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, ViewLayer *view_la
mloopuv = me->mloopuv;
}
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -548,7 +548,7 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, ViewLayer *view_la
if ((scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE) && mpoly->mat_nr != ob->actcol - 1)
continue;
- immBegin(GWN_PRIM_LINE_LOOP, mpoly->totloop);
+ immBegin(GPU_PRIM_LINE_LOOP, mpoly->totloop);
mloopuv = mloopuv_base + mpoly->loopstart;
for (b = 0; b < mpoly->totloop; b++, mloopuv++) {
@@ -658,13 +658,13 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
GPU_blend(true);
- Gwn_VertFormat *format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- Gwn_Batch *face_batch = immBeginBatch(GWN_PRIM_TRIS, tri_count * 3);
+ GPUBatch *face_batch = immBeginBatch(GPU_PRIM_TRIS, tri_count * 3);
for (unsigned int i = 0; i < em->tottri; i++) {
efa = em->looptris[i][0]->f;
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
@@ -686,9 +686,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
immEnd();
/* XXX performance: we should not create and throw away result. */
- GWN_batch_draw(face_batch);
- GWN_batch_program_use_end(face_batch);
- GWN_batch_discard(face_batch);
+ GPU_batch_draw(face_batch);
+ GPU_batch_program_use_end(face_batch);
+ GPU_batch_discard(face_batch);
immUnbindProgram();
@@ -712,7 +712,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
}
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
switch (sima->dt_uv) {
case SI_UVDT_DASH:
@@ -751,8 +751,8 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
}
/* For more efficiency first transfer the entire buffer to vram. */
- Gwn_Batch *loop_batch = immBeginBatchAtMost(GWN_PRIM_LINE_LOOP, bm->totloop);
- Gwn_VertBuf *loop_vbo = loop_batch->verts[0];
+ GPUBatch *loop_batch = immBeginBatchAtMost(GPU_PRIM_LINE_LOOP, bm->totloop);
+ GPUVertBuf *loop_vbo = loop_batch->verts[0];
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
@@ -766,17 +766,17 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
/* Then draw each face contour separately. */
if (loop_vbo->vertex_len != 0) {
- GWN_batch_program_use_begin(loop_batch);
+ GPU_batch_program_use_begin(loop_batch);
unsigned int index = 0, loop_vbo_count;
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
+ GPU_batch_draw_range_ex(loop_batch, index, efa->len, false);
index += efa->len;
}
loop_vbo_count = index;
- GWN_batch_program_use_end(loop_batch);
+ GPU_batch_program_use_end(loop_batch);
immUnbindProgram();
@@ -790,14 +790,14 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
if (interpedges) {
/* Create a color buffer. */
- static Gwn_VertFormat format = { 0 };
+ static GPUVertFormat format = { 0 };
static uint shdr_col;
if (format.attr_len == 0) {
- shdr_col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ shdr_col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
}
- Gwn_VertBuf *vbo_col = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo_col, loop_vbo_count);
+ GPUVertBuf *vbo_col = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo_col, loop_vbo_count);
index = 0;
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
@@ -806,36 +806,36 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
- GWN_vertbuf_attr_set(vbo_col, shdr_col, index++, sel ? col1 : col2);
+ GPU_vertbuf_attr_set(vbo_col, shdr_col, index++, sel ? col1 : col2);
}
}
/* Reuse the UV buffer and add the color buffer. */
- GWN_batch_vertbuf_add_ex(loop_batch, vbo_col, true);
+ GPU_batch_vertbuf_add_ex(loop_batch, vbo_col, true);
/* Now draw each face contour separately with another builtin program. */
- GWN_batch_program_set_builtin(loop_batch, GPU_SHADER_2D_SMOOTH_COLOR);
- gpuBindMatrices(loop_batch->interface);
+ GPU_batch_program_set_builtin(loop_batch, GPU_SHADER_2D_SMOOTH_COLOR);
+ GPU_matrix_bind(loop_batch->interface);
- GWN_batch_program_use_begin(loop_batch);
+ GPU_batch_program_use_begin(loop_batch);
index = 0;
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
+ GPU_batch_draw_range_ex(loop_batch, index, efa->len, false);
index += efa->len;
}
- GWN_batch_program_use_end(loop_batch);
+ GPU_batch_program_use_end(loop_batch);
}
else {
- Gwn_VertFormat *format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
/* Use batch here to avoid problems with `IMM_BUFFER_SIZE`. */
- Gwn_Batch *flat_edges_batch = immBeginBatchAtMost(GWN_PRIM_LINES, loop_vbo_count * 2);
+ GPUBatch *flat_edges_batch = immBeginBatchAtMost(GPU_PRIM_LINES, loop_vbo_count * 2);
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
@@ -852,27 +852,27 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
}
immEnd();
- GWN_batch_draw(flat_edges_batch);
- GWN_batch_discard(flat_edges_batch);
+ GPU_batch_draw(flat_edges_batch);
+ GPU_batch_discard(flat_edges_batch);
immUnbindProgram();
}
}
else {
- GWN_batch_uniform_4fv(loop_batch, "color", col2);
+ GPU_batch_uniform_4fv(loop_batch, "color", col2);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* no nice edges */
- GWN_batch_program_use_begin(loop_batch);
+ GPU_batch_program_use_begin(loop_batch);
index = 0;
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
+ GPU_batch_draw_range_ex(loop_batch, index, efa->len, false);
index += efa->len;
}
- GWN_batch_program_use_end(loop_batch);
+ GPU_batch_program_use_end(loop_batch);
immUnbindProgram();
}
}
@@ -881,7 +881,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
immUnbindProgram();
}
- GWN_batch_discard(loop_batch);
+ GPU_batch_discard(loop_batch);
if (sima->flag & SI_SMOOTH_UV) {
GPU_line_smooth(false);
@@ -894,16 +894,16 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
float cent[2];
bool col_set = false;
- Gwn_VertFormat *format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE);
GPU_point_size(pointsize);
- immBeginAtMost(GWN_PRIM_POINTS, bm->totface);
+ immBeginAtMost(GPU_PRIM_POINTS, bm->totface);
/* unselected faces */
@@ -955,7 +955,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
/* 6. draw uv vertices */
if (drawfaces != 2) { /* 2 means Mesh Face Mode */
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -964,7 +964,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
GPU_point_size(pointsize);
- immBeginAtMost(GWN_PRIM_POINTS, bm->totloop);
+ immBeginAtMost(GPU_PRIM_POINTS, bm->totloop);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
@@ -984,7 +984,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
GPU_point_size(pointsize * 2 + (((int)pointsize % 2) ? (-1) : 0));
imm_cpack(0xFF);
- immBeginAtMost(GWN_PRIM_POINTS, bm->totloop);
+ immBeginAtMost(GPU_PRIM_POINTS, bm->totloop);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
@@ -1004,7 +1004,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
immUniformThemeColor(TH_VERTEX_SELECT);
GPU_point_size(pointsize);
- immBeginAtMost(GWN_PRIM_POINTS, bm->totloop);
+ immBeginAtMost(GPU_PRIM_POINTS, bm->totloop);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index faccb44767f..32bf32b03ab 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -80,6 +80,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -971,7 +972,7 @@ static UvMapVert *uv_select_edgeloop_vertex_map_get(UvVertMap *vmap, BMFace *efa
for (iterv = first; iterv; iterv = iterv->next) {
if (iterv->separate)
first = iterv;
- if (iterv->f == BM_elem_index_get(efa))
+ if (iterv->poly_index == BM_elem_index_get(efa))
return first;
}
@@ -993,9 +994,9 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1,
if (iterv2->separate && iterv2 != first2)
break;
- if (iterv1->f == iterv2->f) {
+ if (iterv1->poly_index == iterv2->poly_index) {
/* if face already tagged, don't do this edge */
- efa = BM_face_at_index(em->bm, iterv1->f);
+ efa = BM_face_at_index(em->bm, iterv1->poly_index);
if (BM_elem_flag_test(efa, BM_ELEM_TAG))
return false;
@@ -1019,8 +1020,8 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1,
if (iterv2->separate && iterv2 != first2)
break;
- if (iterv1->f == iterv2->f) {
- efa = BM_face_at_index(em->bm, iterv1->f);
+ if (iterv1->poly_index == iterv2->poly_index) {
+ efa = BM_face_at_index(em->bm, iterv1->poly_index);
BM_elem_flag_enable(efa, BM_ELEM_TAG);
break;
}
@@ -1231,18 +1232,19 @@ static void uv_select_linked_multi(
for (iterv = vlist; iterv; iterv = iterv->next) {
if (iterv->separate)
startv = iterv;
- if (iterv->f == a)
+ if (iterv->poly_index == a)
break;
}
for (iterv = startv; iterv; iterv = iterv->next) {
if ((startv != iterv) && (iterv->separate))
break;
- else if (!flag[iterv->f]) {
- flag[iterv->f] = 1;
- stack[stacksize] = iterv->f;
+ else if (!flag[iterv->poly_index]) {
+ flag[iterv->poly_index] = 1;
+ stack[stacksize] = iterv->poly_index;
stacksize++;
}
+
}
}
}
@@ -2742,7 +2744,7 @@ static void uv_select_flush_from_tag_sticky_loc_internal(
if (vlist_iter->separate)
start_vlist = vlist_iter;
- if (efa_index == vlist_iter->f)
+ if (efa_index == vlist_iter->poly_index)
break;
vlist_iter = vlist_iter->next;
@@ -2754,12 +2756,12 @@ static void uv_select_flush_from_tag_sticky_loc_internal(
if (vlist_iter != start_vlist && vlist_iter->separate)
break;
- if (efa_index != vlist_iter->f) {
+ if (efa_index != vlist_iter->poly_index) {
BMLoop *l_other;
- efa_vlist = BM_face_at_index(em->bm, vlist_iter->f);
+ efa_vlist = BM_face_at_index(em->bm, vlist_iter->poly_index);
/* tf_vlist = BM_ELEM_CD_GET_VOID_P(efa_vlist, cd_poly_tex_offset); */ /* UNUSED */
- l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex);
+ l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->loop_of_poly_index);
uvedit_uv_select_set(em, scene, l_other, select, false, cd_loop_uv_offset);
}
@@ -4178,14 +4180,14 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
v1coincident = 0;
separated2 = 0;
- efa1 = BM_face_at_index(bm, mv1->f);
+ efa1 = BM_face_at_index(bm, mv1->poly_index);
mvinit2 = vmap->vert[BM_elem_index_get(editedge->v2)];
for (mv2 = mvinit2; mv2; mv2 = mv2->next) {
if (mv2->separate)
mv2sep = mv2;
- efa2 = BM_face_at_index(bm, mv2->f);
+ efa2 = BM_face_at_index(bm, mv2->poly_index);
if (efa1 == efa2) {
/* if v1 is not coincident no point in comparing */
if (v1coincident) {
@@ -4403,6 +4405,15 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_uv_sculpt");
#endif
+ /* Select Element (Sync Select: on) */
+ ED_keymap_editmesh_elem_mode(keyconf, keymap);
+ /* Hack to prevent fall-through, when the button isn't visible. */
+ WM_keymap_add_item(keymap, "MESH_OT_select_mode", FOURKEY, KM_PRESS, 0, 0);
+ /* Select Element (Sync Select: off) */
+ WM_keymap_add_context_enum_set_items(
+ keymap, rna_enum_mesh_select_mode_uv_items, "tool_settings.uv_select_mode",
+ ONEKEY, KM_PRESS, 0, 0);
+
/* Mark edge seam */
WM_keymap_add_item(keymap, "UV_OT_mark_seam", EKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index c3737787933..422c3489e01 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -54,6 +54,7 @@
#include "BKE_customdata.h"
#include "BKE_mesh_mapping.h"
#include "BKE_editmesh.h"
+#include "BKE_layer.h"
#include "DEG_depsgraph.h"
@@ -150,20 +151,11 @@ typedef struct UvEdge {
/* stitch state object */
typedef struct StitchState {
float aspect;
- /* use limit flag */
- bool use_limit;
- /* limit to operator, same as original operator */
- float limit_dist;
- /* snap uv islands together during stitching */
- bool snap_islands;
- /* stitch at midpoints or at islands */
- bool midpoints;
/* object for editmesh */
Object *obedit;
/* editmesh, cached for use in modal handler */
BMEditMesh *em;
- /* clear seams of stitched edges after stitch */
- bool clear_seams;
+
/* element map for getting info about uv connectivity */
UvElementMap *element_map;
/* edge container */
@@ -178,6 +170,8 @@ typedef struct StitchState {
UvEdge *edges;
/* hash for quick lookup of edges */
GHash *edge_hash;
+ /* which islands to stop at (to make active) when pressing 'I' */
+ bool *island_is_stitchable;
/* count of separate uvs and edges */
int total_separate_edges;
@@ -185,18 +179,39 @@ typedef struct StitchState {
/* hold selection related information */
void **selection_stack;
int selection_size;
- /* island that stays in place */
- int static_island;
+
/* store number of primitives per face so that we can allocate the active island buffer later */
unsigned int *tris_per_island;
+ /* preview data */
+ StitchPreviewer *stitch_preview;
+} StitchState;
+/* Stitch state container. */
+typedef struct StitchStateContainer {
+ /* clear seams of stitched edges after stitch */
+ bool clear_seams;
+ /* use limit flag */
+ bool use_limit;
+ /* limit to operator, same as original operator */
+ float limit_dist;
+ /* snap uv islands together during stitching */
+ bool snap_islands;
+ /* stitch at midpoints or at islands */
+ bool midpoints;
/* vert or edge mode used for stitching */
char mode;
/* handle for drawing */
void *draw_handle;
- /* preview data */
- StitchPreviewer *stitch_preview;
-} StitchState;
+ /* island that stays in place */
+ int static_island;
+
+ /* Objects and states are aligned. */
+ int objects_len;
+ Object **objects;
+ StitchState **states;
+
+ int active_object_index;
+} StitchStateContainer;
typedef struct PreviewPosition {
int data_position;
@@ -270,7 +285,7 @@ static void stitch_preview_delete(StitchPreviewer *stitch_preview)
}
/* This function updates the header of the UV editor when the stitch tool updates its settings */
-static void stitch_update_header(StitchState *state, bContext *C)
+static void stitch_update_header(StitchStateContainer *ssc, bContext *C)
{
const char *str = IFACE_(
"Mode(TAB) %s, "
@@ -285,12 +300,13 @@ static void stitch_update_header(StitchState *state, bContext *C)
ScrArea *sa = CTX_wm_area(C);
if (sa) {
- BLI_snprintf(msg, sizeof(msg), str,
- state->mode == STITCH_VERT ? IFACE_("Vertex") : IFACE_("Edge"),
- WM_bool_as_string(state->snap_islands),
- WM_bool_as_string(state->midpoints),
- state->limit_dist,
- WM_bool_as_string(state->use_limit));
+ BLI_snprintf(
+ msg, sizeof(msg), str,
+ ssc->mode == STITCH_VERT ? IFACE_("Vertex") : IFACE_("Edge"),
+ WM_bool_as_string(ssc->snap_islands),
+ WM_bool_as_string(ssc->midpoints),
+ ssc->limit_dist,
+ WM_bool_as_string(ssc->use_limit));
ED_workspace_status_text(C, msg);
}
@@ -320,7 +336,9 @@ static void stitch_uv_rotate(float mat[2][2], float medianPoint[2], float uv[2],
}
/* check if two uvelements are stitchable. This should only operate on -different- separate UvElements */
-static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
+static bool stitch_check_uvs_stitchable(
+ UvElement *element, UvElement *element_iter,
+ StitchStateContainer *ssc, StitchState *state)
{
BMesh *bm = state->em->bm;
float limit;
@@ -329,9 +347,9 @@ static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_i
return 0;
}
- limit = state->limit_dist;
+ limit = ssc->limit_dist;
- if (state->use_limit) {
+ if (ssc->use_limit) {
MLoopUV *luv, *luv_iter;
BMLoop *l;
@@ -355,7 +373,9 @@ static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_i
}
}
-static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
+static bool stitch_check_edges_stitchable(
+ UvEdge *edge, UvEdge *edge_iter,
+ StitchStateContainer *ssc, StitchState *state)
{
BMesh *bm = state->em->bm;
float limit;
@@ -364,9 +384,9 @@ static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, Stitc
return 0;
}
- limit = state->limit_dist;
+ limit = ssc->limit_dist;
- if (state->use_limit) {
+ if (ssc->use_limit) {
BMLoop *l;
MLoopUV *luv_orig1, *luv_iter1;
MLoopUV *luv_orig2, *luv_iter2;
@@ -397,27 +417,30 @@ static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, Stitc
}
}
-static bool stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
+static bool stitch_check_uvs_state_stitchable(
+ UvElement *element, UvElement *element_iter,
+ StitchStateContainer *ssc, StitchState *state)
{
- if ((state->snap_islands && element->island == element_iter->island) ||
- (!state->midpoints && element->island == element_iter->island))
+ if ((ssc->snap_islands && element->island == element_iter->island) ||
+ (!ssc->midpoints && element->island == element_iter->island))
{
return 0;
}
- return stitch_check_uvs_stitchable(element, element_iter, state);
+ return stitch_check_uvs_stitchable(element, element_iter, ssc, state);
}
-
-static bool stitch_check_edges_state_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
+static bool stitch_check_edges_state_stitchable(
+ UvEdge *edge, UvEdge *edge_iter,
+ StitchStateContainer *ssc, StitchState *state)
{
- if ((state->snap_islands && edge->element->island == edge_iter->element->island) ||
- (!state->midpoints && edge->element->island == edge_iter->element->island))
+ if ((ssc->snap_islands && edge->element->island == edge_iter->element->island) ||
+ (!ssc->midpoints && edge->element->island == edge_iter->element->island))
{
return 0;
}
- return stitch_check_edges_stitchable(edge, edge_iter, state);
+ return stitch_check_edges_stitchable(edge, edge_iter, ssc, state);
}
/* calculate snapping for islands */
@@ -489,9 +512,10 @@ static void stitch_calculate_island_snapping(
int face_preview_pos = preview_position[BM_elem_index_get(element->l->f)].data_position;
stitch_uv_rotate(rotation_mat, island_stitch_data[i].medianPoint,
- preview->preview_polys + face_preview_pos + 2 * element->tfindex, state->aspect);
+ preview->preview_polys + face_preview_pos + 2 * element->loop_of_poly_index,
+ state->aspect);
- add_v2_v2(preview->preview_polys + face_preview_pos + 2 * element->tfindex,
+ add_v2_v2(preview->preview_polys + face_preview_pos + 2 * element->loop_of_poly_index,
island_stitch_data[i].translation);
}
}
@@ -505,8 +529,8 @@ static void stitch_calculate_island_snapping(
static void stitch_island_calculate_edge_rotation(
- UvEdge *edge, StitchState *state, UVVertAverage *uv_average, unsigned int *uvfinal_map,
- IslandStitchData *island_stitch_data)
+ UvEdge *edge, StitchStateContainer *ssc, StitchState *state, UVVertAverage *uv_average,
+ unsigned int *uvfinal_map, IslandStitchData *island_stitch_data)
{
BMesh *bm = state->em->bm;
UvElement *element1, *element2;
@@ -522,7 +546,7 @@ static void stitch_island_calculate_edge_rotation(
luv1 = CustomData_bmesh_get(&bm->ldata, element1->l->head.data, CD_MLOOPUV);
luv2 = CustomData_bmesh_get(&bm->ldata, element2->l->head.data, CD_MLOOPUV);
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
index1 = uvfinal_map[element1 - state->element_map->buf];
index2 = uvfinal_map[element2 - state->element_map->buf];
}
@@ -561,7 +585,7 @@ static void stitch_island_calculate_edge_rotation(
static void stitch_island_calculate_vert_rotation(
- UvElement *element, StitchState *state,
+ UvElement *element, StitchStateContainer *ssc, StitchState *state,
IslandStitchData *island_stitch_data)
{
float edgecos = 1.0f, edgesin = 0.0f;
@@ -571,7 +595,7 @@ static void stitch_island_calculate_vert_rotation(
int rot_elem = 0, rot_elem_neg = 0;
BMLoop *l;
- if (element->island == state->static_island && !state->midpoints)
+ if (element->island == ssc->static_island && !ssc->midpoints)
return;
l = element->l;
@@ -581,12 +605,12 @@ static void stitch_island_calculate_vert_rotation(
element_iter = state->element_map->vert[index];
for (; element_iter; element_iter = element_iter->next) {
- if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)) {
+ if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) {
int index_tmp1, index_tmp2;
float normal[2];
/* only calculate rotation against static island uv verts */
- if (!state->midpoints && element_iter->island != state->static_island)
+ if (!ssc->midpoints && element_iter->island != ssc->static_island)
continue;
index_tmp1 = element_iter - state->element_map->buf;
@@ -608,7 +632,7 @@ static void stitch_island_calculate_vert_rotation(
}
}
- if (state->midpoints) {
+ if (ssc->midpoints) {
rotation /= 2.0f;
rotation_neg /= 2.0f;
}
@@ -622,6 +646,9 @@ static void stitch_island_calculate_vert_rotation(
static void state_delete(StitchState *state)
{
if (state) {
+ if (state->island_is_stitchable) {
+ MEM_freeN(state->island_is_stitchable);
+ }
if (state->element_map) {
BM_uv_element_map_free(state->element_map);
}
@@ -653,6 +680,18 @@ static void state_delete(StitchState *state)
}
}
+static void state_delete_all(StitchStateContainer *ssc)
+{
+ if (ssc) {
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ state_delete(ssc->states[ob_index]);
+ }
+ MEM_freeN(ssc->states);
+ MEM_freeN(ssc->objects);
+ MEM_freeN(ssc);
+ }
+}
+
static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *state)
{
UvEdge *edges = state->edges;
@@ -735,7 +774,7 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *
/* checks for remote uvs that may be stitched with a certain uv, flags them if stitchable. */
static void determine_uv_stitchability(
- UvElement *element, StitchState *state,
+ UvElement *element, StitchStateContainer *ssc, StitchState *state,
IslandStitchData *island_stitch_data)
{
int vert_index;
@@ -749,7 +788,7 @@ static void determine_uv_stitchability(
for (; element_iter; element_iter = element_iter->next) {
if (element_iter->separate) {
- if (stitch_check_uvs_stitchable(element, element_iter, state)) {
+ if (stitch_check_uvs_stitchable(element, element_iter, ssc, state)) {
island_stitch_data[element_iter->island].stitchableCandidate = 1;
island_stitch_data[element->island].stitchableCandidate = 1;
element->flag |= STITCH_STITCHABLE_CANDIDATE;
@@ -759,13 +798,13 @@ static void determine_uv_stitchability(
}
static void determine_uv_edge_stitchability(
- UvEdge *edge, StitchState *state,
+ UvEdge *edge, StitchStateContainer *ssc, StitchState *state,
IslandStitchData *island_stitch_data)
{
UvEdge *edge_iter = edge->first;
for (; edge_iter; edge_iter = edge_iter->next) {
- if (stitch_check_edges_stitchable(edge, edge_iter, state)) {
+ if (stitch_check_edges_stitchable(edge, edge_iter, ssc, state)) {
island_stitch_data[edge_iter->element->island].stitchableCandidate = 1;
island_stitch_data[edge->element->island].stitchableCandidate = 1;
edge->flag |= STITCH_STITCHABLE_CANDIDATE;
@@ -790,16 +829,16 @@ static void stitch_set_face_preview_buffer_position(
/* setup face preview for all coincident uvs and their faces */
static void stitch_setup_face_preview_for_uv_group(
- UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
- PreviewPosition *preview_position)
+ UvElement *element, StitchStateContainer *ssc, StitchState *state,
+ IslandStitchData *island_stitch_data, PreviewPosition *preview_position)
{
StitchPreviewer *preview = state->stitch_preview;
/* static island does not change so returning immediately */
- if (state->snap_islands && !state->midpoints && state->static_island == element->island)
+ if (ssc->snap_islands && !ssc->midpoints && ssc->static_island == element->island)
return;
- if (state->snap_islands) {
+ if (ssc->snap_islands) {
island_stitch_data[element->island].addedForPreview = 1;
}
@@ -812,11 +851,18 @@ static void stitch_setup_face_preview_for_uv_group(
/* checks if uvs are indeed stitchable and registers so that they can be shown in preview */
static void stitch_validate_uv_stitchability(
- UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
- PreviewPosition *preview_position)
+ UvElement *element, StitchStateContainer *ssc, StitchState *state,
+ IslandStitchData *island_stitch_data, PreviewPosition *preview_position)
{
- UvElement *element_iter;
StitchPreviewer *preview = state->stitch_preview;
+
+ /* If not the active object, then it's unstitchable */
+ if (ssc->states[ssc->active_object_index] != state) {
+ preview->num_unstitchable++;
+ return;
+ }
+
+ UvElement *element_iter;
int vert_index;
BMLoop *l;
@@ -830,11 +876,11 @@ static void stitch_validate_uv_stitchability(
if (element_iter->separate) {
if (element_iter == element)
continue;
- if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
- if ((element_iter->island == state->static_island) || (element->island == state->static_island)) {
+ if (stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) {
+ if ((element_iter->island == ssc->static_island) || (element->island == ssc->static_island)) {
element->flag |= STITCH_STITCHABLE;
preview->num_stitchable++;
- stitch_setup_face_preview_for_uv_group(element, state, island_stitch_data, preview_position);
+ stitch_setup_face_preview_for_uv_group(element, ssc, state, island_stitch_data, preview_position);
return;
}
}
@@ -849,21 +895,28 @@ static void stitch_validate_uv_stitchability(
static void stitch_validate_edge_stitchability(
- UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data,
- PreviewPosition *preview_position)
+ UvEdge *edge, StitchStateContainer *ssc, StitchState *state,
+ IslandStitchData *island_stitch_data, PreviewPosition *preview_position)
{
- UvEdge *edge_iter = edge->first;
StitchPreviewer *preview = state->stitch_preview;
+ /* If not the active object, then it's unstitchable */
+ if (ssc->states[ssc->active_object_index] != state) {
+ preview->num_unstitchable++;
+ return;
+ }
+
+ UvEdge *edge_iter = edge->first;
+
for (; edge_iter; edge_iter = edge_iter->next) {
if (edge_iter == edge)
continue;
- if (stitch_check_edges_state_stitchable(edge, edge_iter, state)) {
- if ((edge_iter->element->island == state->static_island) || (edge->element->island == state->static_island)) {
+ if (stitch_check_edges_state_stitchable(edge, edge_iter, ssc, state)) {
+ if ((edge_iter->element->island == ssc->static_island) || (edge->element->island == ssc->static_island)) {
edge->flag |= STITCH_STITCHABLE;
preview->num_stitchable++;
- stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], state, island_stitch_data, preview_position);
- stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], state, island_stitch_data, preview_position);
+ stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], ssc, state, island_stitch_data, preview_position);
+ stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], ssc, state, island_stitch_data, preview_position);
return;
}
}
@@ -879,7 +932,7 @@ static void stitch_validate_edge_stitchability(
static void stitch_propagate_uv_final_position(
Scene *scene,
UvElement *element, int index, PreviewPosition *preview_position,
- UVVertAverage *final_position, StitchState *state,
+ UVVertAverage *final_position, StitchStateContainer *ssc, StitchState *state,
const bool final)
{
BMesh *bm = state->em->bm;
@@ -907,13 +960,13 @@ static void stitch_propagate_uv_final_position(
else {
int face_preview_pos = preview_position[BM_elem_index_get(element_iter->l->f)].data_position;
if (face_preview_pos != STITCH_NO_PREVIEW) {
- copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex,
- final_position[index].uv);
+ copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->loop_of_poly_index,
+ final_position[index].uv);
}
}
/* end of calculations, keep only the selection flag */
- if ((!state->snap_islands) || ((!state->midpoints) && (element_iter->island == state->static_island))) {
+ if ((!ssc->snap_islands) || ((!ssc->midpoints) && (element_iter->island == ssc->static_island))) {
element_iter->flag &= STITCH_SELECTED;
}
@@ -923,18 +976,20 @@ static void stitch_propagate_uv_final_position(
}
/* main processing function. It calculates preview and final positions. */
-static int stitch_process_data(StitchState *state, Scene *scene, int final)
+static int stitch_process_data(
+ StitchStateContainer *ssc, StitchState *state, Scene *scene, int final)
{
int i;
StitchPreviewer *preview;
IslandStitchData *island_stitch_data = NULL;
- int previous_island = state->static_island;
+ int previous_island = ssc->static_island;
BMesh *bm = state->em->bm;
BMFace *efa;
BMIter iter;
UVVertAverage *final_position = NULL;
+ bool is_active_state = (state == ssc->states[ssc->active_object_index]);
- char stitch_midpoints = state->midpoints;
+ char stitch_midpoints = ssc->midpoints;
/* used to map uv indices to uvaverage indices for selection */
unsigned int *uvfinal_map = NULL;
/* per face preview position in preview buffer */
@@ -965,32 +1020,41 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
*****************************************/
for (i = 0; i < state->selection_size; i++) {
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
UvElement *element = (UvElement *)state->selection_stack[i];
- determine_uv_stitchability(element, state, island_stitch_data);
+ determine_uv_stitchability(element, ssc, state, island_stitch_data);
}
else {
UvEdge *edge = (UvEdge *)state->selection_stack[i];
- determine_uv_edge_stitchability(edge, state, island_stitch_data);
+ determine_uv_edge_stitchability(edge, ssc, state, island_stitch_data);
}
}
- /* set static island to one that is added for preview */
- state->static_island %= state->element_map->totalIslands;
- while (!(island_stitch_data[state->static_island].stitchableCandidate)) {
- state->static_island++;
- state->static_island %= state->element_map->totalIslands;
- /* this is entirely possible if for example limit stitching with no stitchable verts or no selection */
- if (state->static_island == previous_island)
- break;
+ /* remember stitchable candidates as places the 'I' button */
+ /* will stop at. */
+ for (int island_idx = 0; island_idx < state->element_map->totalIslands; island_idx++) {
+ state->island_is_stitchable[island_idx] = island_stitch_data[island_idx].stitchableCandidate ? true : false;
+ }
+
+ if (is_active_state) {
+ /* set static island to one that is added for preview */
+ ssc->static_island %= state->element_map->totalIslands;
+ while (!(island_stitch_data[ssc->static_island].stitchableCandidate)) {
+ ssc->static_island++;
+ ssc->static_island %= state->element_map->totalIslands;
+ /* this is entirely possible if for example limit stitching with no stitchable verts or no selection */
+ if (ssc->static_island == previous_island) {
+ break;
+ }
+ }
}
for (i = 0; i < state->selection_size; i++) {
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
UvElement *element = (UvElement *)state->selection_stack[i];
if (element->flag & STITCH_STITCHABLE_CANDIDATE) {
element->flag &= ~STITCH_STITCHABLE_CANDIDATE;
- stitch_validate_uv_stitchability(element, state, island_stitch_data, preview_position);
+ stitch_validate_uv_stitchability(element, ssc, state, island_stitch_data, preview_position);
}
else {
/* add to preview for unstitchable */
@@ -1001,7 +1065,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
UvEdge *edge = (UvEdge *)state->selection_stack[i];
if (edge->flag & STITCH_STITCHABLE_CANDIDATE) {
edge->flag &= ~STITCH_STITCHABLE_CANDIDATE;
- stitch_validate_edge_stitchability(edge, state, island_stitch_data, preview_position);
+ stitch_validate_edge_stitchability(edge, ssc, state, island_stitch_data, preview_position);
}
else {
preview->num_unstitchable++;
@@ -1009,10 +1073,90 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
}
+ /*********************************************************************
+ * Setup the stitchable & unstitchable preview buffers and fill *
+ * them with the appropriate data *
+ *********************************************************************/
+ if (!final) {
+ BMLoop *l;
+ MLoopUV *luv;
+ int stitchBufferIndex = 0, unstitchBufferIndex = 0;
+ int preview_size = (ssc->mode == STITCH_VERT) ? 2 : 4;
+ /* initialize the preview buffers */
+ preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * preview_size, "stitch_preview_stitchable_data");
+ preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * preview_size, "stitch_preview_unstitchable_data");
+
+ /* will cause cancel and freeing of all data structures so OK */
+ if (!preview->preview_stitchable || !preview->preview_unstitchable) {
+ return 0;
+ }
+
+ /* fill the appropriate preview buffers */
+ if (ssc->mode == STITCH_VERT) {
+ for (i = 0; i < state->total_separate_uvs; i++) {
+ UvElement *element = (UvElement *)state->uvs[i];
+ if (element->flag & STITCH_STITCHABLE) {
+ l = element->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv);
+
+ stitchBufferIndex++;
+ }
+ else if (element->flag & STITCH_SELECTED) {
+ l = element->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv);
+ unstitchBufferIndex++;
+ }
+ }
+ }
+ else {
+ for (i = 0; i < state->total_separate_edges; i++) {
+ UvEdge *edge = state->edges + i;
+ UvElement *element1 = state->uvs[edge->uv1];
+ UvElement *element2 = state->uvs[edge->uv2];
+
+ if (edge->flag & STITCH_STITCHABLE) {
+ l = element1->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv);
+
+ l = element2->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv);
+
+ stitchBufferIndex++;
+ BLI_assert(stitchBufferIndex <= preview->num_stitchable);
+ }
+ else if (edge->flag & STITCH_SELECTED) {
+ l = element1->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv);
+
+ l = element2->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv);
+
+ unstitchBufferIndex++;
+ BLI_assert(unstitchBufferIndex <= preview->num_unstitchable);
+ }
+ }
+ }
+ }
+
+ if (ssc->states[ssc->active_object_index] != state) {
+ /* This is not the active object/state, exit here */
+ MEM_freeN(island_stitch_data);
+ MEM_freeN(preview_position);
+ return 1;
+ }
+
/*****************************************
* Setup preview for stitchable islands *
*****************************************/
- if (state->snap_islands) {
+ if (ssc->snap_islands) {
for (i = 0; i < state->element_map->totalIslands; i++) {
if (island_stitch_data[i].addedForPreview) {
int numOfIslandUVs = 0, j;
@@ -1027,26 +1171,24 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
/*********************************************************************
- * Setup the preview buffers and fill them with the appropriate data *
+ * Setup the remaining preview buffers and fill them with the *
+ * appropriate data *
*********************************************************************/
if (!final) {
BMIter liter;
BMLoop *l;
MLoopUV *luv;
unsigned int buffer_index = 0;
- int stitchBufferIndex = 0, unstitchBufferIndex = 0;
- int preview_size = (state->mode == STITCH_VERT) ? 2 : 4;
+
/* initialize the preview buffers */
preview->preview_polys = (float *)MEM_mallocN(preview->preview_uvs * sizeof(float) * 2, "tri_uv_stitch_prev");
preview->uvs_per_polygon = MEM_mallocN(preview->num_polys * sizeof(*preview->uvs_per_polygon), "tri_uv_stitch_prev");
- preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * preview_size, "stitch_preview_stitchable_data");
- preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * preview_size, "stitch_preview_unstitchable_data");
- preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[state->static_island] * sizeof(float) * 6, "static_island_preview_tris");
+ preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[ssc->static_island] * sizeof(float) * 6, "static_island_preview_tris");
- preview->num_static_tris = state->tris_per_island[state->static_island];
+ preview->num_static_tris = state->tris_per_island[ssc->static_island];
/* will cause cancel and freeing of all data structures so OK */
- if (!preview->preview_polys || !preview->preview_stitchable || !preview->preview_unstitchable) {
+ if (!preview->preview_polys) {
return 0;
}
@@ -1067,7 +1209,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
}
- if (element->island == state->static_island) {
+ /* if this is the static_island on the active object */
+ if (element->island == ssc->static_island) {
BMLoop *fl = BM_FACE_FIRST_LOOP(efa);
MLoopUV *fuv = CustomData_bmesh_get(&bm->ldata, fl->head.data, CD_MLOOPUV);
@@ -1090,67 +1233,13 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
}
}
-
- /* fill the appropriate preview buffers */
- if (state->mode == STITCH_VERT) {
- for (i = 0; i < state->total_separate_uvs; i++) {
- UvElement *element = (UvElement *)state->uvs[i];
- if (element->flag & STITCH_STITCHABLE) {
- l = element->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
-
- copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv);
-
- stitchBufferIndex++;
- }
- else if (element->flag & STITCH_SELECTED) {
- l = element->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
-
- copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv);
- unstitchBufferIndex++;
- }
- }
- }
- else {
- for (i = 0; i < state->total_separate_edges; i++) {
- UvEdge *edge = state->edges + i;
- UvElement *element1 = state->uvs[edge->uv1];
- UvElement *element2 = state->uvs[edge->uv2];
-
- if (edge->flag & STITCH_STITCHABLE) {
- l = element1->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv);
-
- l = element2->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv);
-
- stitchBufferIndex++;
- BLI_assert(stitchBufferIndex <= preview->num_stitchable);
- }
- else if (edge->flag & STITCH_SELECTED) {
- l = element1->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv);
-
- l = element2->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv);
-
- unstitchBufferIndex++;
- BLI_assert(unstitchBufferIndex <= preview->num_unstitchable);
- }
- }
- }
}
/******************************************************
* Here we calculate the final coordinates of the uvs *
******************************************************/
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average");
uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map");
}
@@ -1160,7 +1249,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
/* first pass, calculate final position for stitchable uvs of the static island */
for (i = 0; i < state->selection_size; i++) {
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
UvElement *element = state->selection_stack[i];
if (element->flag & STITCH_STITCHABLE) {
@@ -1176,21 +1265,21 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
copy_v2_v2(final_position[i].uv, luv->uv);
final_position[i].count = 1;
- if (state->snap_islands && element->island == state->static_island && !stitch_midpoints)
+ if (ssc->snap_islands && element->island == ssc->static_island && !stitch_midpoints)
continue;
element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
for ( ; element_iter; element_iter = element_iter->next) {
if (element_iter->separate) {
- if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
+ if (stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) {
l = element_iter->l;
luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
if (stitch_midpoints) {
add_v2_v2(final_position[i].uv, luv->uv);
final_position[i].count++;
}
- else if (element_iter->island == state->static_island) {
+ else if (element_iter->island == ssc->static_island) {
/* if multiple uvs on the static island exist,
* last checked remains. to disambiguate we need to limit or use
* edge stitch */
@@ -1226,11 +1315,11 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
state->uvs[edge->uv1]->flag |= STITCH_STITCHABLE;
state->uvs[edge->uv2]->flag |= STITCH_STITCHABLE;
- if (state->snap_islands && edge->element->island == state->static_island && !stitch_midpoints)
+ if (ssc->snap_islands && edge->element->island == ssc->static_island && !stitch_midpoints)
continue;
for (edge_iter = edge->first; edge_iter; edge_iter = edge_iter->next) {
- if (stitch_check_edges_state_stitchable (edge, edge_iter, state)) {
+ if (stitch_check_edges_state_stitchable(edge, edge_iter, ssc, state)) {
l = state->uvs[edge_iter->uv1]->l;
luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
l = state->uvs[edge_iter->uv2]->l;
@@ -1242,7 +1331,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
add_v2_v2(final_position[edge->uv2].uv, luv2->uv);
final_position[edge->uv2].count++;
}
- else if (edge_iter->element->island == state->static_island) {
+ else if (edge_iter->element->island == ssc->static_island) {
copy_v2_v2(final_position[edge->uv1].uv, luv1->uv);
copy_v2_v2(final_position[edge->uv2].uv, luv2->uv);
}
@@ -1253,7 +1342,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
/* take mean position here. For edge case, this can't be done inside the loop for shared uvverts */
- if (state->mode == STITCH_EDGE && stitch_midpoints) {
+ if (ssc->mode == STITCH_EDGE && stitch_midpoints) {
for (i = 0; i < state->total_separate_uvs; i++) {
final_position[i].uv[0] /= final_position[i].count;
final_position[i].uv[1] /= final_position[i].count;
@@ -1261,8 +1350,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
/* second pass, calculate island rotation and translation before modifying any uvs */
- if (state->snap_islands) {
- if (state->mode == STITCH_VERT) {
+ if (ssc->snap_islands) {
+ if (ssc->mode == STITCH_VERT) {
for (i = 0; i < state->selection_size; i++) {
UvElement *element = state->selection_stack[i];
@@ -1290,13 +1379,13 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
(state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) &&
(state->uvs[edge->uv2]->flag & STITCH_STITCHABLE))
{
- stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data);
+ stitch_island_calculate_edge_rotation(edge, ssc, state, final_position, uvfinal_map, island_stitch_data);
island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = true;
}
}
/* clear seams of stitched edges */
- if (final && state->clear_seams) {
+ if (final && ssc->clear_seams) {
for (i = 0; i < state->total_separate_edges; i++) {
UvEdge *edge = state->edges + i;
if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) &&
@@ -1311,7 +1400,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
UvElement *element = state->selection_stack[i];
if (!island_stitch_data[element->island].use_edge_rotation) {
if (element->flag & STITCH_STITCHABLE) {
- stitch_island_calculate_vert_rotation(element, state, island_stitch_data);
+ stitch_island_calculate_vert_rotation(element, ssc, state, island_stitch_data);
}
}
}
@@ -1328,7 +1417,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
/* accumulate each islands' translation from stitchable elements. it is important to do here
- * because in final pass MTFaces get modified and result is zero. */
+ * because in final pass MTFaces get modified and result is zero. */
island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0];
island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1];
island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
@@ -1341,13 +1430,13 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
UvEdge *edge = state->selection_stack[i];
if (edge->flag & STITCH_STITCHABLE) {
- stitch_island_calculate_edge_rotation(edge, state, final_position, NULL, island_stitch_data);
+ stitch_island_calculate_edge_rotation(edge, ssc, state, final_position, NULL, island_stitch_data);
island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = true;
}
}
/* clear seams of stitched edges */
- if (final && state->clear_seams) {
+ if (final && ssc->clear_seams) {
for (i = 0; i < state->selection_size; i++) {
UvEdge *edge = state->selection_stack[i];
if (edge->flag & STITCH_STITCHABLE) {
@@ -1360,30 +1449,30 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
/* third pass, propagate changes to coincident uvs */
for (i = 0; i < state->selection_size; i++) {
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
UvElement *element = state->selection_stack[i];
- stitch_propagate_uv_final_position(scene, element, i, preview_position, final_position, state, final);
+ stitch_propagate_uv_final_position(scene, element, i, preview_position, final_position, ssc, state, final);
}
else {
UvEdge *edge = state->selection_stack[i];
stitch_propagate_uv_final_position(
- scene, state->uvs[edge->uv1], edge->uv1, preview_position, final_position, state, final);
+ scene, state->uvs[edge->uv1], edge->uv1, preview_position, final_position, ssc, state, final);
stitch_propagate_uv_final_position(
- scene, state->uvs[edge->uv2], edge->uv2, preview_position, final_position, state, final);
+ scene, state->uvs[edge->uv2], edge->uv2, preview_position, final_position, ssc, state, final);
edge->flag &= (STITCH_SELECTED | STITCH_BOUNDARY);
}
}
/* final pass, calculate Island translation/rotation if needed */
- if (state->snap_islands) {
+ if (ssc->snap_islands) {
stitch_calculate_island_snapping(state, preview_position, preview, island_stitch_data, final);
}
MEM_freeN(final_position);
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
MEM_freeN(uvfinal_map);
}
MEM_freeN(island_stitch_data);
@@ -1392,6 +1481,17 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
return 1;
}
+static int stitch_process_data_all(StitchStateContainer *ssc, Scene *scene, int final)
+{
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ if (!stitch_process_data(ssc, ssc->states[ob_index], scene, final)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
/* Stitch hash initialization functions */
static unsigned int uv_edge_hash(const void *key)
{
@@ -1476,13 +1576,13 @@ static void stitch_select_uv(UvElement *element, StitchState *state, int always_
}
}
-static void stitch_switch_selection_mode(StitchState *state)
+static void stitch_set_selection_mode(StitchState *state, const char from_stitch_mode)
{
void **old_selection_stack = state->selection_stack;
int old_selection_size = state->selection_size;
state->selection_size = 0;
- if (state->mode == STITCH_VERT) {
+ if (from_stitch_mode == STITCH_VERT) {
int i;
state->selection_stack = MEM_mallocN(state->total_separate_edges * sizeof(*state->selection_stack),
"stitch_new_edge_selection_stack");
@@ -1503,7 +1603,6 @@ static void stitch_switch_selection_mode(StitchState *state)
element->flag &= ~STITCH_SELECTED;
}
- state->mode = STITCH_EDGE;
}
else {
int i;
@@ -1520,12 +1619,26 @@ static void stitch_switch_selection_mode(StitchState *state)
edge->flag &= ~STITCH_SELECTED;
}
- state->mode = STITCH_VERT;
}
MEM_freeN(old_selection_stack);
}
-static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal, float aspect)
+static void stitch_switch_selection_mode_all(StitchStateContainer *ssc)
+{
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ stitch_set_selection_mode(ssc->states[ob_index], ssc->mode);
+ }
+
+ if (ssc->mode == STITCH_VERT) {
+ ssc->mode = STITCH_EDGE;
+ }
+ else {
+ ssc->mode = STITCH_VERT;
+ }
+}
+
+static void stitch_calculate_edge_normal(
+ BMEditMesh *em, UvEdge *edge, float *normal, float aspect)
{
BMLoop *l1 = edge->element->l;
MLoopUV *luv1, *luv2;
@@ -1534,7 +1647,7 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no
luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_MLOOPUV);
luv2 = CustomData_bmesh_get(&em->bm->ldata, l1->next->head.data, CD_MLOOPUV);
- sub_v2_v2v2(tangent, luv2->uv, luv1->uv);
+ sub_v2_v2v2(tangent, luv2->uv, luv1->uv);
tangent[1] /= aspect;
@@ -1546,123 +1659,132 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no
/**
*/
-static void stitch_draw_vbo(Gwn_VertBuf *vbo, Gwn_PrimType prim_type, const float col[4])
+static void stitch_draw_vbo(GPUVertBuf *vbo, GPUPrimType prim_type, const float col[4])
{
- Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
- GWN_batch_uniform_4fv(batch, "color", col);
- GWN_batch_draw(batch);
- GWN_batch_discard(batch);
+ GPUBatch *batch = GPU_batch_create_ex(prim_type, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
+ GPU_batch_uniform_4fv(batch, "color", col);
+ GPU_batch_draw(batch);
+ GPU_batch_discard(batch);
}
/* TODO make things pretier : store batches inside StitchPreviewer instead of the bare verts pos */
static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
{
- int j, index = 0;
- unsigned int num_line = 0, num_tri, tri_idx = 0, line_idx = 0;
- StitchState *state = (StitchState *)arg;
- StitchPreviewer *stitch_preview = state->stitch_preview;
- Gwn_VertBuf *vbo, *vbo_line;
- float col[4];
-
- static Gwn_VertFormat format = { 0 };
- static unsigned int pos_id;
- if (format.attr_len == 0) {
- pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- }
- GPU_blend(true);
+ StitchStateContainer *ssc = (StitchStateContainer *)arg;
- /* Static Tris */
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_ACTIVE, col);
- vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, stitch_preview->num_static_tris * 3);
- for (int i = 0; i < stitch_preview->num_static_tris * 3; i++) {
- GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->static_tris[i * 2]);
- }
- stitch_draw_vbo(vbo, GWN_PRIM_TRIS, col);
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ int j, index = 0;
+ unsigned int num_line = 0, num_tri, tri_idx = 0, line_idx = 0;
+ StitchState *state = ssc->states[ob_index];
+ StitchPreviewer *stitch_preview = state->stitch_preview;
+ GPUVertBuf *vbo, *vbo_line;
+ float col[4];
+ static GPUVertFormat format = { 0 };
+ static unsigned int pos_id;
+ if (format.attr_len == 0) {
+ pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ }
- /* Preview Polys */
- for (int i = 0; i < stitch_preview->num_polys; i++)
- num_line += stitch_preview->uvs_per_polygon[i];
+ GPU_blend(true);
- num_tri = num_line - 2 * stitch_preview->num_polys;
+ /* Static Tris */
+ if (stitch_preview->static_tris) {
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_ACTIVE, col);
+ vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, stitch_preview->num_static_tris * 3);
+ for (int i = 0; i < stitch_preview->num_static_tris * 3; i++) {
+ GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->static_tris[i * 2]);
+ }
+ stitch_draw_vbo(vbo, GPU_PRIM_TRIS, col);
+ }
- /* we need to convert the polys into triangles / lines */
- vbo = GWN_vertbuf_create_with_format(&format);
- vbo_line = GWN_vertbuf_create_with_format(&format);
+ /* Preview Polys */
+ if (stitch_preview->preview_polys) {
+ for (int i = 0; i < stitch_preview->num_polys; i++)
+ num_line += stitch_preview->uvs_per_polygon[i];
- GWN_vertbuf_data_alloc(vbo, num_tri * 3);
- GWN_vertbuf_data_alloc(vbo_line, num_line * 2);
+ num_tri = num_line - 2 * stitch_preview->num_polys;
- for (int i = 0; i < stitch_preview->num_polys; i++) {
- BLI_assert(stitch_preview->uvs_per_polygon[i] >= 3);
+ /* we need to convert the polys into triangles / lines */
+ vbo = GPU_vertbuf_create_with_format(&format);
+ vbo_line = GPU_vertbuf_create_with_format(&format);
- /* Start line */
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]);
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + 2]);
+ GPU_vertbuf_data_alloc(vbo, num_tri * 3);
+ GPU_vertbuf_data_alloc(vbo_line, num_line * 2);
- for (j = 1; j < stitch_preview->uvs_per_polygon[i] - 1; ++j) {
- GWN_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index]);
- GWN_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]);
- GWN_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]);
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]);
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]);
- }
+ for (int i = 0; i < stitch_preview->num_polys; i++) {
+ BLI_assert(stitch_preview->uvs_per_polygon[i] >= 3);
- /* Closing line */
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]);
- /* j = uvs_per_polygon[i] - 1*/
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + j * 2]);
+ /* Start line */
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]);
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + 2]);
- index += stitch_preview->uvs_per_polygon[i] * 2;
- }
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_FACE, col);
- stitch_draw_vbo(vbo, GWN_PRIM_TRIS, col);
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_EDGE, col);
- stitch_draw_vbo(vbo_line, GWN_PRIM_LINES, col);
+ for (j = 1; j < stitch_preview->uvs_per_polygon[i] - 1; ++j) {
+ GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index]);
+ GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]);
+ GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]);
- GPU_blend(false);
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]);
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]);
+ }
+ /* Closing line */
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]);
+ /* j = uvs_per_polygon[i] - 1*/
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + j * 2]);
- /* draw stitch vert/lines preview */
- if (state->mode == STITCH_VERT) {
- GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE) * 2.0f);
+ index += stitch_preview->uvs_per_polygon[i] * 2;
+ }
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col);
- vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable);
- for (int i = 0; i < stitch_preview->num_stitchable; i++) {
- GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]);
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_FACE, col);
+ stitch_draw_vbo(vbo, GPU_PRIM_TRIS, col);
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_EDGE, col);
+ stitch_draw_vbo(vbo_line, GPU_PRIM_LINES, col);
}
- stitch_draw_vbo(vbo, GWN_PRIM_POINTS, col);
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col);
- vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable);
- for (int i = 0; i < stitch_preview->num_unstitchable; i++) {
- GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]);
- }
- stitch_draw_vbo(vbo, GWN_PRIM_POINTS, col);
- }
- else {
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col);
- vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable * 2);
- for (int i = 0; i < stitch_preview->num_stitchable * 2; i++) {
- GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]);
+ GPU_blend(false);
+
+ /* draw stitch vert/lines preview */
+ if (ssc->mode == STITCH_VERT) {
+ GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE) * 2.0f);
+
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col);
+ vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable);
+ for (int i = 0; i < stitch_preview->num_stitchable; i++) {
+ GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]);
+ }
+ stitch_draw_vbo(vbo, GPU_PRIM_POINTS, col);
+
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col);
+ vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable);
+ for (int i = 0; i < stitch_preview->num_unstitchable; i++) {
+ GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]);
+ }
+ stitch_draw_vbo(vbo, GPU_PRIM_POINTS, col);
}
- stitch_draw_vbo(vbo, GWN_PRIM_LINES, col);
+ else {
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col);
+ vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable * 2);
+ for (int i = 0; i < stitch_preview->num_stitchable * 2; i++) {
+ GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]);
+ }
+ stitch_draw_vbo(vbo, GPU_PRIM_LINES, col);
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col);
- vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable * 2);
- for (int i = 0; i < stitch_preview->num_unstitchable * 2; i++) {
- GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]);
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col);
+ vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable * 2);
+ for (int i = 0; i < stitch_preview->num_unstitchable * 2; i++) {
+ GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]);
+ }
+ stitch_draw_vbo(vbo, GPU_PRIM_LINES, col);
}
- stitch_draw_vbo(vbo, GWN_PRIM_LINES, col);
}
}
@@ -1688,7 +1810,9 @@ static UvEdge *uv_edge_get(BMLoop *l, StitchState *state)
return BLI_ghash_lookup(state->edge_hash, &tmp_edge);
}
-static int stitch_init(bContext *C, wmOperator *op)
+static StitchState *stitch_init(
+ bContext *C, wmOperator *op,
+ StitchStateContainer *ssc, Object *obedit)
{
/* for fast edge lookup... */
GHash *edge_hash;
@@ -1706,47 +1830,16 @@ static int stitch_init(bContext *C, wmOperator *op)
StitchState *state;
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
- ARegion *ar = CTX_wm_region(C);
float aspx, aspy;
- Object *obedit = CTX_data_edit_object(C);
+
BMEditMesh *em = BKE_editmesh_from_object(obedit);
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- if (!ar)
- return 0;
-
- state = MEM_callocN(sizeof(StitchState), "stitch state");
-
- op->customdata = state;
+ state = MEM_callocN(sizeof(StitchState), "stitch state obj");
/* initialize state */
- state->use_limit = RNA_boolean_get(op->ptr, "use_limit");
- state->limit_dist = RNA_float_get(op->ptr, "limit");
state->obedit = obedit;
state->em = em;
- state->snap_islands = RNA_boolean_get(op->ptr, "snap_islands");
- state->static_island = RNA_int_get(op->ptr, "static_island");
- state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap");
- state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams");
- if (RNA_struct_property_is_set(op->ptr, "mode")) {
- state->mode = RNA_enum_get(op->ptr, "mode");
- }
- else {
- if (ts->uv_flag & UV_SYNC_SELECTION) {
- if (ts->selectmode & SCE_SELECT_VERTEX)
- state->mode = STITCH_VERT;
- else
- state->mode = STITCH_EDGE;
- }
- else {
- if (ts->uv_selectmode & UV_SELECT_VERTEX) {
- state->mode = STITCH_VERT;
- }
- else {
- state->mode = STITCH_EDGE;
- }
- }
- }
/* in uv synch selection, all uv's are visible */
if (ts->uv_flag & UV_SYNC_SELECTION) {
@@ -1757,16 +1850,12 @@ static int stitch_init(bContext *C, wmOperator *op)
}
if (!state->element_map) {
state_delete(state);
- return 0;
+ return NULL;
}
ED_uvedit_get_aspect(scene, obedit, em->bm, &aspx, &aspy);
state->aspect = aspx / aspy;
- /* Entirely possible if redoing last operator that static island is bigger than total number of islands.
- * This ensures we get no hang in the island checking code in stitch_stitch_process_data. */
- state->static_island %= state->element_map->totalIslands;
-
/* Count 'unique' uvs */
for (i = 0; i < state->element_map->totalUVs; i++) {
if (state->element_map->buf[i].separate) {
@@ -1785,11 +1874,11 @@ static int stitch_init(bContext *C, wmOperator *op)
state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->totalUVs, "uv_stitch_unique_map");
/* Allocate the edge stack */
edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
- all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "stitch_all_edges");
+ all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "ssc_edges");
if (!state->uvs || !map || !edge_hash || !all_edges) {
state_delete(state);
- return 0;
+ return NULL;
}
/* So that we can use this as index for the UvElements */
@@ -1858,7 +1947,7 @@ static int stitch_init(bContext *C, wmOperator *op)
/* I assume any system will be able to at least allocate an iterator :p */
if (!edges) {
state_delete(state);
- return 0;
+ return NULL;
}
state->total_separate_edges = total_edges;
@@ -1908,7 +1997,8 @@ static int stitch_init(bContext *C, wmOperator *op)
state->selection_size = 0;
/* Load old selection if redoing operator with different settings */
- if (RNA_struct_property_is_set(op->ptr, "selection")) {
+ /* WIP */
+ if (false && RNA_struct_property_is_set(op->ptr, "selection")) {
int faceIndex, elementIndex;
UvElement *element;
enum StitchModes stored_mode = RNA_enum_get(op->ptr, "stored_mode");
@@ -1961,16 +2051,15 @@ static int stitch_init(bContext *C, wmOperator *op)
}
/* if user has switched the operator mode after operation, we need to convert
* the stored format */
- if (state->mode != stored_mode) {
- state->mode = stored_mode;
- stitch_switch_selection_mode(state);
+ if (ssc->mode != stored_mode) {
+ stitch_set_selection_mode(state, stored_mode);
}
/* Clear the selection */
RNA_collection_clear(op->ptr, "selection");
}
else {
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack");
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -2022,22 +2111,154 @@ static int stitch_init(bContext *C, wmOperator *op)
}
}
- if (!stitch_process_data(state, scene, false)) {
+ state->island_is_stitchable = MEM_callocN(sizeof(bool) * state->element_map->totalIslands, "stitch I stops");
+ if (!state->island_is_stitchable) {
+ state_delete(state);
+ return NULL;
+ }
+ if (!stitch_process_data(ssc, state, scene, false)) {
state_delete(state);
+ return NULL;
+ }
+
+ return state;
+}
+
+static bool goto_next_island(StitchStateContainer *ssc)
+{
+ StitchState *active_state = ssc->states[ssc->active_object_index];
+ StitchState *original_active_state = active_state;
+
+ int original_island = ssc->static_island;
+
+ do {
+ ssc->static_island++;
+ if (ssc->static_island >= active_state->element_map->totalIslands) {
+ /* go to next object */
+ ssc->active_object_index++;
+ ssc->active_object_index %= ssc->objects_len;
+
+ active_state = ssc->states[ssc->active_object_index];
+ ssc->static_island = 0;
+ }
+
+ if (active_state->island_is_stitchable[ssc->static_island]) {
+ /* We're at an island to make active */
+ return true;
+ }
+ } while (!(active_state == original_active_state &&
+ ssc->static_island == original_island));
+
+ return false;
+}
+
+static int stitch_init_all(bContext *C, wmOperator *op)
+{
+ ARegion *ar = CTX_wm_region(C);
+ if (!ar)
+ return 0;
+
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = scene->toolsettings;
+
+ StitchStateContainer *ssc = MEM_callocN(sizeof(StitchStateContainer), "stitch collection");
+
+ op->customdata = ssc;
+
+ ssc->use_limit = RNA_boolean_get(op->ptr, "use_limit");
+ ssc->limit_dist = RNA_float_get(op->ptr, "limit");
+ ssc->snap_islands = RNA_boolean_get(op->ptr, "snap_islands");
+ ssc->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap");
+ ssc->clear_seams = RNA_boolean_get(op->ptr, "clear_seams");
+ ssc->active_object_index = RNA_int_get(op->ptr, "active_object_index");
+ ssc->static_island = 0;
+
+ if (RNA_struct_property_is_set(op->ptr, "mode")) {
+ ssc->mode = RNA_enum_get(op->ptr, "mode");
+ }
+ else {
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ if (ts->selectmode & SCE_SELECT_VERTEX)
+ ssc->mode = STITCH_VERT;
+ else
+ ssc->mode = STITCH_EDGE;
+ }
+ else {
+ if (ts->uv_selectmode & UV_SELECT_VERTEX) {
+ ssc->mode = STITCH_VERT;
+ }
+ else {
+ ssc->mode = STITCH_EDGE;
+ }
+ }
+ }
+
+ ssc->objects_len = 0;
+ ssc->states = NULL;
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(view_layer, &objects_len);
+
+ if (objects_len == 0) {
+ MEM_freeN(objects);
+ state_delete_all(ssc);
return 0;
}
- state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, state, REGION_DRAW_POST_VIEW);
+ ssc->objects = MEM_callocN(sizeof(Object *) * objects_len, "Object *ssc->objects");
+ ssc->states = MEM_callocN(sizeof(StitchState *) * objects_len, "StitchState");
+ ssc->objects_len = 0;
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+
+ StitchState *stitch_state_ob = stitch_init(C, op, ssc, obedit);
+
+ if (stitch_state_ob) {
+ ssc->objects[ssc->objects_len] = obedit;
+ ssc->states[ssc->objects_len] = stitch_state_ob;
+ ssc->objects_len++;
+ }
+ }
+
+ MEM_freeN(objects);
+
+ if (ssc->objects_len == 0) {
+ state_delete_all(ssc);
+ return 0;
+ }
+
+ ssc->active_object_index %= ssc->objects_len;
+
+ ssc->static_island = RNA_int_get(op->ptr, "static_island");
+
+ StitchState *state = ssc->states[ssc->active_object_index];
+ ssc->static_island %= state->element_map->totalIslands;
+
+ /* If the initial active object doesn't have any stitchable islands */
+ /* then no active island will be seen in the UI. Make sure we're on */
+ /* a stitchable object and island. */
+ if (!state->island_is_stitchable[ssc->static_island]) {
+ goto_next_island(ssc);
+ state = ssc->states[ssc->active_object_index];
+ }
+
+ /* process active stitchobj again now that it can detect it's the active stitchobj */
+ stitch_process_data(ssc, state, scene, false);
+
+ stitch_update_header(ssc, C);
+
+ ssc->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, ssc, REGION_DRAW_POST_VIEW);
- stitch_update_header(state, C);
return 1;
}
static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *obedit = CTX_data_edit_object(C);
- if (!stitch_init(C, op))
+ if (!stitch_init_all(C, op))
return OPERATOR_CANCELLED;
WM_event_add_modal_handler(C, op);
@@ -2047,34 +2268,37 @@ static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(even
static void stitch_exit(bContext *C, wmOperator *op, int finished)
{
- StitchState *state;
Scene *scene;
SpaceImage *sima;
ScrArea *sa = CTX_wm_area(C);
- Object *obedit;
scene = CTX_data_scene(C);
- obedit = CTX_data_edit_object(C);
sima = CTX_wm_space_image(C);
- state = (StitchState *)op->customdata;
+ StitchStateContainer *ssc = (StitchStateContainer *)op->customdata;
+ StitchState *state = ssc->states[ssc->active_object_index];
+ Object *obedit = state->obedit;
if (finished) {
int i;
- RNA_float_set(op->ptr, "limit", state->limit_dist);
- RNA_boolean_set(op->ptr, "use_limit", state->use_limit);
- RNA_boolean_set(op->ptr, "snap_islands", state->snap_islands);
- RNA_int_set(op->ptr, "static_island", state->static_island);
- RNA_boolean_set(op->ptr, "midpoint_snap", state->midpoints);
- RNA_enum_set(op->ptr, "mode", state->mode);
- RNA_enum_set(op->ptr, "stored_mode", state->mode);
+ RNA_float_set(op->ptr, "limit", ssc->limit_dist);
+ RNA_boolean_set(op->ptr, "use_limit", ssc->use_limit);
+ RNA_boolean_set(op->ptr, "snap_islands", ssc->snap_islands);
+ RNA_boolean_set(op->ptr, "midpoint_snap", ssc->midpoints);
+ RNA_boolean_set(op->ptr, "clear_seams", ssc->clear_seams);
+ RNA_enum_set(op->ptr, "mode", ssc->mode);
+ RNA_enum_set(op->ptr, "stored_mode", ssc->mode);
+ RNA_int_set(op->ptr, "active_object_index", ssc->active_object_index);
+
+ RNA_int_set(op->ptr, "static_island", ssc->static_island);
/* Store selection for re-execution of stitch */
+ /* WIP */
for (i = 0; i < state->selection_size; i++) {
UvElement *element;
PointerRNA itemptr;
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
element = state->selection_stack[i];
}
else {
@@ -2083,7 +2307,7 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
RNA_collection_add(op->ptr, "selection", &itemptr);
RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->l->f));
- RNA_int_set(&itemptr, "element_index", element->tfindex);
+ RNA_int_set(&itemptr, "element_index", element->loop_of_poly_index);
}
uvedit_live_unwrap_update(sima, scene, obedit);
@@ -2092,12 +2316,13 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
if (sa)
ED_workspace_status_text(C, NULL);
- ED_region_draw_cb_exit(CTX_wm_region(C)->type, state->draw_handle);
+ ED_region_draw_cb_exit(CTX_wm_region(C)->type, ssc->draw_handle);
DEG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- state_delete(state);
+ state_delete_all(ssc);
+
op->customdata = NULL;
}
@@ -2112,9 +2337,9 @@ static int stitch_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- if (!stitch_init(C, op))
+ if (!stitch_init_all(C, op))
return OPERATOR_CANCELLED;
- if (stitch_process_data((StitchState *)op->customdata, scene, 1)) {
+ if (stitch_process_data_all((StitchStateContainer *)op->customdata, scene, 1)) {
stitch_exit(C, op, 1);
return OPERATOR_FINISHED;
}
@@ -2124,7 +2349,8 @@ static int stitch_exec(bContext *C, wmOperator *op)
}
}
-static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, StitchState *state)
+static StitchState *stitch_select(
+ bContext *C, Scene *scene, const wmEvent *event, StitchStateContainer *ssc)
{
/* add uv under mouse to processed uv's */
float co[2];
@@ -2134,36 +2360,60 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
- if (state->mode == STITCH_VERT) {
- if (uv_find_nearest_vert(
- scene, ima, state->obedit, co, 0.0f, &hit))
+ if (ssc->mode == STITCH_VERT) {
+ if (uv_find_nearest_vert_multi(
+ scene, ima, ssc->objects, ssc->objects_len, co, 0.0f, &hit))
{
/* Add vertex to selection, deselect all common uv's of vert other
* than selected and update the preview. This behavior was decided so that
* you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */
+ /* find StitchState from hit->ob */
+ StitchState *state = NULL;
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ if (hit.ob == ssc->objects[ob_index]) {
+ state = ssc->states[ob_index];
+ break;
+ }
+ }
+
/* This works due to setting of tmp in find nearest uv vert */
UvElement *element = BM_uv_element_get(state->element_map, hit.efa, hit.l);
stitch_select_uv(element, state, false);
+ return state;
}
}
else {
- if (uv_find_nearest_edge(
- scene, ima, state->obedit, co, &hit))
+ if (uv_find_nearest_edge_multi(
+ scene, ima, ssc->objects, ssc->objects_len, co, &hit))
{
+ /* find StitchState from hit->ob */
+ StitchState *state = NULL;
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ if (hit.ob == ssc->objects[ob_index]) {
+ state = ssc->states[ob_index];
+ break;
+ }
+ }
+
UvEdge *edge = uv_edge_get(hit.l, state);
stitch_select_edge(edge, state, false);
+
+ return state;
}
}
+
+ return NULL;
}
static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- StitchState *state;
+ StitchStateContainer *ssc;
Scene *scene = CTX_data_scene(C);
- state = (StitchState *)op->customdata;
+ ssc = op->customdata;
+ StitchState *active_state = ssc->states[ssc->active_object_index];
switch (event->type) {
case MIDDLEMOUSE:
@@ -2177,9 +2427,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case LEFTMOUSE:
if (event->shift && (U.flag & USER_LMOUSESELECT)) {
if (event->val == KM_PRESS) {
- stitch_select(C, scene, event, state);
+ StitchState *selected_state = stitch_select(C, scene, event, ssc);
- if (!stitch_process_data(state, scene, false)) {
+ if (selected_state && !stitch_process_data(ssc, selected_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2190,7 +2440,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case PADENTER:
case RETKEY:
if (event->val == KM_PRESS) {
- if (stitch_process_data(state, scene, true)) {
+ if (stitch_process_data(ssc, active_state, scene, true)) {
stitch_exit(C, op, 1);
return OPERATOR_FINISHED;
}
@@ -2206,8 +2456,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case PADPLUSKEY:
case WHEELUPMOUSE:
if (event->val == KM_PRESS && event->alt) {
- state->limit_dist += 0.01f;
- if (!stitch_process_data(state, scene, false)) {
+ ssc->limit_dist += 0.01f;
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2220,9 +2470,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case PADMINUS:
case WHEELDOWNMOUSE:
if (event->val == KM_PRESS && event->alt) {
- state->limit_dist -= 0.01f;
- state->limit_dist = MAX2(0.01f, state->limit_dist);
- if (!stitch_process_data(state, scene, false)) {
+ ssc->limit_dist -= 0.01f;
+ ssc->limit_dist = MAX2(0.01f, ssc->limit_dist);
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2235,8 +2485,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Use Limit (Default off) */
case LKEY:
if (event->val == KM_PRESS) {
- state->use_limit = !state->use_limit;
- if (!stitch_process_data(state, scene, false)) {
+ ssc->use_limit = !ssc->use_limit;
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2246,12 +2496,23 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case IKEY:
if (event->val == KM_PRESS) {
- state->static_island++;
- state->static_island %= state->element_map->totalIslands;
+ /* Move to next island and maybe next object */
- if (!stitch_process_data(state, scene, false)) {
- stitch_cancel(C, op);
- return OPERATOR_CANCELLED;
+ if (goto_next_island(ssc)) {
+ StitchState *new_active_state = ssc->states[ssc->active_object_index];
+
+ /* active_state is the origional active state */
+ if (active_state != new_active_state) {
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
+ stitch_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ if (!stitch_process_data(ssc, new_active_state, scene, false)) {
+ stitch_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
}
break;
}
@@ -2259,8 +2520,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case MKEY:
if (event->val == KM_PRESS) {
- state->midpoints = !state->midpoints;
- if (!stitch_process_data(state, scene, false)) {
+ ssc->midpoints = !ssc->midpoints;
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2274,9 +2535,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
}
if (event->val == KM_PRESS && !(U.flag & USER_LMOUSESELECT)) {
- stitch_select(C, scene, event, state);
+ StitchState *selected_state = stitch_select(C, scene, event, ssc);
- if (!stitch_process_data(state, scene, false)) {
+ if (selected_state && !stitch_process_data(ssc, selected_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2287,8 +2548,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* snap islands on/off */
case SKEY:
if (event->val == KM_PRESS) {
- state->snap_islands = !state->snap_islands;
- if (!stitch_process_data(state, scene, false)) {
+ ssc->snap_islands = !ssc->snap_islands;
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2301,9 +2562,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* switch between edge/vertex mode */
case TABKEY:
if (event->val == KM_PRESS) {
- stitch_switch_selection_mode(state);
+ stitch_switch_selection_mode_all(ssc);
- if (!stitch_process_data(state, scene, false)) {
+ if (!stitch_process_data_all(ssc, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2315,8 +2576,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
/* if updated settings, renew feedback message */
- stitch_update_header(state, C);
+ stitch_update_header(ssc, C);
ED_region_tag_redraw(CTX_wm_region(C));
+
return OPERATOR_RUNNING_MODAL;
}
@@ -2352,14 +2614,16 @@ void UV_OT_stitch(wmOperatorType *ot)
"Limit distance in normalized coordinates", 0.0, FLT_MAX);
RNA_def_int(ot->srna, "static_island", 0, 0, INT_MAX, "Static Island",
"Island that stays in place when stitching islands", 0, INT_MAX);
+ RNA_def_int(ot->srna, "active_object_index", 0, 0, INT_MAX, "Active Object",
+ "Index of the active object", 0, INT_MAX);
RNA_def_boolean(ot->srna, "midpoint_snap", 0, "Snap At Midpoint",
"UVs are stitched at midpoint instead of at static island");
RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams",
"Clear seams of stitched edges");
RNA_def_enum(ot->srna, "mode", stitch_modes, STITCH_VERT, "Operation Mode",
"Use vertex or edge stitching");
- prop = RNA_def_enum(ot->srna, "stored_mode", stitch_modes, STITCH_VERT, "Stored Operation Mode",
- "Use vertex or edge stitching");
+ prop = RNA_def_enum(ot->srna, "stored_mode", stitch_modes, STITCH_VERT, "Stored Operation Mode",
+ "Use vertex or edge stitching");
RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", "");
/* Selection should not be editable or viewed in toolbar */