diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index 349afe7a93e..2a56611db95 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -8311,13 +8311,6 @@ class VIEW3D_PT_overlay_grease_pencil_options(Panel): layout.prop(overlay, "use_gpencil_onion_skin", text="Onion Skin") col = layout.column() - row = col.row() - row.prop(overlay, "use_gpencil_grid", text="") - sub = row.row(align=True) - sub.active = overlay.use_gpencil_grid - sub.prop(overlay, "gpencil_grid_opacity", text="Canvas", slider=True) - sub.prop(overlay, "use_gpencil_canvas_xray", text="", icon='XRAY') - row = col.row() row.prop(overlay, "use_gpencil_fade_layers", text="") sub = row.row() @@ -8353,6 +8346,44 @@ class VIEW3D_PT_overlay_grease_pencil_options(Panel): row.prop(overlay, "gpencil_vertex_paint_opacity", text="Opacity", slider=True) +class VIEW3D_PT_overlay_grease_pencil_canvas_options(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'HEADER' + bl_parent_id = "VIEW3D_PT_overlay_grease_pencil_options" + bl_label = "Canvas" + bl_ui_units_x = 13 + + @classmethod + def poll(cls, context): + ob = context.object + return ob and ob.type == 'GREASEPENCIL' + + def draw(self, context): + layout = self.layout + view = context.space_data + overlay = view.overlay + + col = layout.column() + col.active = overlay.use_gpencil_grid + row = col.row() + row.prop(overlay, "use_gpencil_grid", text="") + sub = row.row(align=True) + sub.prop(overlay, "gpencil_grid_opacity", text="Canvas", slider=True) + sub.prop(overlay, "use_gpencil_canvas_xray", text="", icon='XRAY') + + col = col.column(align=True) + row = col.row(align=True) + row.prop(overlay, "gpencil_grid_subdivisions") + row = col.row(align=True) + row.prop(overlay, "gpencil_grid_color", text="") + + col = col.column(align=True) + row = col.row() + row.prop(overlay, "gpencil_grid_scale", text="Scale", expand=True) + row = col.row() + row.prop(overlay, "gpencil_grid_offset", text="Offset", expand=True) + + class VIEW3D_PT_quad_view(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'UI' @@ -9878,6 +9909,7 @@ classes = ( VIEW3D_PT_transform_orientations, VIEW3D_PT_overlay_gpencil_options, VIEW3D_PT_overlay_grease_pencil_options, + VIEW3D_PT_overlay_grease_pencil_canvas_options, VIEW3D_PT_context_properties, VIEW3D_PT_paint_vertex_context_menu, VIEW3D_PT_paint_texture_context_menu, diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 755d8a57273..08f567c034a 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -31,7 +31,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 27 +#define BLENDER_FILE_SUBVERSION 28 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 2b0a09f2b4a..3756aac70ef 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -4884,6 +4884,22 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) hide_simulation_node_skip_socket_value(*bmain); } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 403, 28)) { + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = reinterpret_cast(sl); + copy_v3_fl(v3d->overlay.gpencil_grid_color, 0.5f); + copy_v2_fl(v3d->overlay.gpencil_grid_scale, 1.0f); + copy_v2_fl(v3d->overlay.gpencil_grid_offset, 0.0f); + v3d->overlay.gpencil_grid_subdivisions = 4; + } + } + } + } + } + /** * Always bump subversion in BKE_blender_version.h when adding versioning * code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check. diff --git a/source/blender/draw/engines/overlay/overlay_grease_pencil.cc b/source/blender/draw/engines/overlay/overlay_grease_pencil.cc index 0ba818443fe..cc5b37a660f 100644 --- a/source/blender/draw/engines/overlay/overlay_grease_pencil.cc +++ b/source/blender/draw/engines/overlay/overlay_grease_pencil.cc @@ -124,68 +124,77 @@ void OVERLAY_grease_pencil_cache_init(OVERLAY_Data *vedata) (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE)) == 0); const bool grid_xray = (v3d->gp_flag & V3D_GP_SHOW_GRID_XRAY); - if (show_grid && show_overlays) { - const float3 base_color = float3(0.5f); - const float4 col_grid = float4(base_color, v3d->overlay.gpencil_grid_opacity); - - float4x4 mat = ob->object_to_world(); - - const GreasePencil &grease_pencil = *static_cast(ob->data); - const blender::bke::greasepencil::Layer &layer = *grease_pencil.get_active_layer(); - - if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR) { - mat = layer.to_world_space(*ob); - } - const View3DCursor *cursor = &scene->cursor; - - /* Set the grid in the selected axis */ - switch (ts->gp_sculpt.lock_axis) { - case GP_LOCKAXIS_X: - std::swap(mat[0], mat[2]); - break; - case GP_LOCKAXIS_Y: - std::swap(mat[1], mat[2]); - break; - case GP_LOCKAXIS_Z: - /* Default. */ - break; - case GP_LOCKAXIS_CURSOR: { - mat = float4x4(cursor->matrix()); - break; - } - case GP_LOCKAXIS_VIEW: - /* view aligned */ - DRW_view_viewmat_get(nullptr, mat.ptr(), true); - break; - } - - mat *= 2.0f; - - if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) { - mat.location() = cursor->location; - } - else { - mat.location() = layer.to_world_space(*ob).location(); - } - - const int gridlines = 4; - const int line_count = gridlines * 4 + 2; - - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA; - state |= (grid_xray) ? DRW_STATE_DEPTH_ALWAYS : DRW_STATE_DEPTH_LESS_EQUAL; - - DRW_PASS_CREATE(psl->grease_pencil_canvas_ps, state); - - sh = OVERLAY_shader_gpencil_canvas(); - grp = DRW_shgroup_create(sh, psl->grease_pencil_canvas_ps); - DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); - DRW_shgroup_uniform_vec4_copy(grp, "color", col_grid); - DRW_shgroup_uniform_vec3_copy(grp, "xAxis", mat[0]); - DRW_shgroup_uniform_vec3_copy(grp, "yAxis", mat[1]); - DRW_shgroup_uniform_vec3_copy(grp, "origin", mat[3]); - DRW_shgroup_uniform_int_copy(grp, "halfLineCount", line_count / 2); - DRW_shgroup_call_procedural_lines(grp, nullptr, line_count); + if (!ob || (ob->type != OB_GREASE_PENCIL) || !show_grid || !show_overlays) { + return; } + const float3 base_color = float3(v3d->overlay.gpencil_grid_color); + const float4 col_grid = float4(base_color, v3d->overlay.gpencil_grid_opacity); + + float4x4 mat = ob->object_to_world(); + + const GreasePencil &grease_pencil = *static_cast(ob->data); + if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR && grease_pencil.has_active_layer()) { + const blender::bke::greasepencil::Layer &layer = *grease_pencil.get_active_layer(); + mat = layer.to_world_space(*ob); + } + const View3DCursor *cursor = &scene->cursor; + + /* Set the grid in the selected axis */ + switch (ts->gp_sculpt.lock_axis) { + case GP_LOCKAXIS_X: + std::swap(mat[0], mat[2]); + break; + case GP_LOCKAXIS_Y: + std::swap(mat[1], mat[2]); + break; + case GP_LOCKAXIS_Z: + /* Default. */ + break; + case GP_LOCKAXIS_CURSOR: { + mat = float4x4(cursor->matrix()); + break; + } + case GP_LOCKAXIS_VIEW: + /* view aligned */ + DRW_view_viewmat_get(nullptr, mat.ptr(), true); + break; + } + + /* Note: This is here to match the legacy size. */ + mat *= 2.0f; + + if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) { + mat.location() = cursor->location; + } + else if (grease_pencil.has_active_layer()) { + const blender::bke::greasepencil::Layer &layer = *grease_pencil.get_active_layer(); + mat.location() = layer.to_world_space(*ob).location(); + } + /* Local transform of the grid from the overlay settings. */ + const float3 offset = float3( + v3d->overlay.gpencil_grid_offset[0], v3d->overlay.gpencil_grid_offset[1], 0.0f); + const float3 scale = float3( + v3d->overlay.gpencil_grid_scale[0], v3d->overlay.gpencil_grid_scale[1], 0.0f); + const float4x4 local_transform = math::from_loc_scale(offset, scale); + mat = mat * local_transform; + + const int gridlines = v3d->overlay.gpencil_grid_subdivisions; + const int line_count = gridlines * 4 + 2; + + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA; + state |= (grid_xray) ? DRW_STATE_DEPTH_ALWAYS : DRW_STATE_DEPTH_LESS_EQUAL; + + DRW_PASS_CREATE(psl->grease_pencil_canvas_ps, state); + + sh = OVERLAY_shader_gpencil_canvas(); + grp = DRW_shgroup_create(sh, psl->grease_pencil_canvas_ps); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); + DRW_shgroup_uniform_vec4_copy(grp, "color", col_grid); + DRW_shgroup_uniform_vec3_copy(grp, "xAxis", mat[0]); + DRW_shgroup_uniform_vec3_copy(grp, "yAxis", mat[1]); + DRW_shgroup_uniform_vec3_copy(grp, "origin", mat[3]); + DRW_shgroup_uniform_int_copy(grp, "halfLineCount", line_count / 2); + DRW_shgroup_call_procedural_lines(grp, nullptr, line_count); } void OVERLAY_edit_grease_pencil_cache_populate(OVERLAY_Data *vedata, Object *ob) diff --git a/source/blender/makesdna/DNA_view3d_defaults.h b/source/blender/makesdna/DNA_view3d_defaults.h index 96af90946b8..542837b6c07 100644 --- a/source/blender/makesdna/DNA_view3d_defaults.h +++ b/source/blender/makesdna/DNA_view3d_defaults.h @@ -61,6 +61,10 @@ \ .gpencil_paper_opacity = 0.5f, \ .gpencil_grid_opacity = 0.9f, \ + .gpencil_grid_color = {0.5f, 0.5f, 0.5f}, \ + .gpencil_grid_scale = {1.0f, 1.0f}, \ + .gpencil_grid_offset = {0.0f, 0.0f}, \ + .gpencil_grid_subdivisions = 4, \ .gpencil_vertex_paint_opacity = 1.0f, \ .normals_constant_screen_size = 7.0f, \ } diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 45287b30f76..c39cae45e0b 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -238,6 +238,12 @@ typedef struct View3DOverlay { float gpencil_grid_opacity; float gpencil_fade_layer; + /* Grease Pencil canvas settings. */ + float gpencil_grid_color[3]; + float gpencil_grid_scale[2]; + float gpencil_grid_offset[2]; + int gpencil_grid_subdivisions; + /** Factor for mixing vertex paint with original color */ float gpencil_vertex_paint_opacity; /** Handles display type for curves. */ diff --git a/source/blender/makesrna/intern/rna_space.cc b/source/blender/makesrna/intern/rna_space.cc index 33b5f7a9cf6..f2d12271f98 100644 --- a/source/blender/makesrna/intern/rna_space.cc +++ b/source/blender/makesrna/intern/rna_space.cc @@ -5018,6 +5018,32 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Opacity", "Canvas grid opacity"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, nullptr); + prop = RNA_def_property(srna, "gpencil_grid_color", PROP_FLOAT, PROP_COLOR); + RNA_def_property_float_sdna(prop, nullptr, "overlay.gpencil_grid_color"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Grid Color", "Canvas grid color"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, nullptr); + + prop = RNA_def_property(srna, "gpencil_grid_scale", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, nullptr, "overlay.gpencil_grid_scale"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "Scale", "Canvas grid scale"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, nullptr); + + prop = RNA_def_property(srna, "gpencil_grid_offset", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_sdna(prop, nullptr, "overlay.gpencil_grid_offset"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "Offset", "Canvas grid offset"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, nullptr); + + prop = RNA_def_property(srna, "gpencil_grid_subdivisions", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, nullptr, "overlay.gpencil_grid_subdivisions"); + RNA_def_property_range(prop, 1, 100); + RNA_def_property_ui_text(prop, "Subdivisions", "Canvas grid subdivisions"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, nullptr); + /* Paper opacity factor */ prop = RNA_def_property(srna, "gpencil_fade_objects", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, nullptr, "overlay.gpencil_paper_opacity");