From 5685ec595289ef1d797fe8ea4fd50dd11126500a Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 25 Jun 2024 14:02:34 +0200 Subject: [PATCH] GPv3: Draw Tool: Use brush strength for fill opacity Makes sure the the brush strength is used to write to the fill opacity. The conditions for what attribute to skip when copying previous data from the curves geometry was getting a bit complicated so this part got refactored. --- .../sculpt_paint/grease_pencil_paint.cc | 80 +++++++++---------- 1 file changed, 36 insertions(+), 44 deletions(-) diff --git a/source/blender/editors/sculpt_paint/grease_pencil_paint.cc b/source/blender/editors/sculpt_paint/grease_pencil_paint.cc index 615f0eb1791..86683fe6210 100644 --- a/source/blender/editors/sculpt_paint/grease_pencil_paint.cc +++ b/source/blender/editors/sculpt_paint/grease_pencil_paint.cc @@ -24,6 +24,7 @@ #include "DEG_depsgraph_query.hh" #include "DNA_brush_enums.h" +#include "DNA_material_types.h" #include "ED_curves.hh" #include "ED_grease_pencil.hh" @@ -315,36 +316,6 @@ struct PaintOperationExecutor { BLI_assert(drawing_ != nullptr); } - /* Attributes that are defined explicitly and should not be copied from original geometry. */ - Set skipped_attribute_ids(const bke::AttrDomain domain) const - { - switch (domain) { - case bke::AttrDomain::Point: - if (vertex_color_) { - return {"position", "radius", "opacity", "vertex_color"}; - } - else { - return {"position", "radius", "opacity"}; - } - case bke::AttrDomain::Curve: - if (fill_color_) { - return {"curve_type", - "material_index", - "cyclic", - "softness", - "start_cap", - "end_cap", - "fill_color"}; - } - else { - return {"curve_type", "material_index", "cyclic", "softness", "start_cap", "end_cap"}; - } - default: - return {}; - } - return {}; - } - float randomize_radius(PaintOperation &self, const float distance, const float radius, @@ -376,7 +347,7 @@ struct PaintOperationExecutor { const float opacity, const float pressure) { - if (!use_settings_random_ || !(settings_->draw_random_press > 0.0f)) { + if (!use_settings_random_ || !(settings_->draw_random_strength > 0.0f)) { return opacity; } float random_factor = [&]() { @@ -400,7 +371,8 @@ struct PaintOperationExecutor { void process_start_sample(PaintOperation &self, const bContext &C, const InputSample &start_sample, - const int material_index) + const int material_index, + const bool use_fill) { const float2 start_coords = start_sample.mouse_position; const RegionView3D *rv3d = CTX_wm_region_view3d(&C); @@ -439,14 +411,19 @@ struct PaintOperationExecutor { const IndexRange curve_points = curves.points_by_curve()[active_curve]; const int last_active_point = curve_points.last(); + Set point_attributes_to_skip; + Set curve_attributes_to_skip; curves.positions_for_write()[last_active_point] = start_location; drawing_->radii_for_write()[last_active_point] = start_radius; drawing_->opacities_for_write()[last_active_point] = start_opacity; + point_attributes_to_skip.add_multiple({"position", "radius", "opacity"}); if (vertex_color_) { drawing_->vertex_colors_for_write()[last_active_point] = *vertex_color_; + point_attributes_to_skip.add("vertex_color"); } - if (fill_color_) { + if (use_fill && fill_color_) { drawing_->fill_colors_for_write()[active_curve] = *fill_color_; + curve_attributes_to_skip.add("fill_color"); } bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); @@ -459,12 +436,17 @@ struct PaintOperationExecutor { cyclic.span[active_curve] = false; materials.span[active_curve] = material_index; softness.span[active_curve] = softness_; + curve_attributes_to_skip.add_multiple({"material_index", "cyclic", "softness"}); + cyclic.finish(); + materials.finish(); + softness.finish(); /* Only set the attribute if the type is not the default or if it already exists. */ if (settings_->caps_type != GP_STROKE_CAP_TYPE_ROUND || attributes.contains("start_cap")) { bke::SpanAttributeWriter start_caps = attributes.lookup_or_add_for_write_span("start_cap", bke::AttrDomain::Curve); start_caps.span[active_curve] = settings_->caps_type; + curve_attributes_to_skip.add("start_cap"); start_caps.finish(); } @@ -472,12 +454,20 @@ struct PaintOperationExecutor { bke::SpanAttributeWriter end_caps = attributes.lookup_or_add_for_write_span( "end_cap", bke::AttrDomain::Curve); end_caps.span[active_curve] = settings_->caps_type; + curve_attributes_to_skip.add("end_cap"); end_caps.finish(); } - cyclic.finish(); - materials.finish(); - softness.finish(); + if (use_fill && (start_opacity < 1.0f || attributes.contains("fill_opacity"))) { + bke::SpanAttributeWriter fill_opacities = + attributes.lookup_or_add_for_write_span( + "fill_opacity", + bke::AttrDomain::Curve, + bke::AttributeInitVArray(VArray::ForSingle(1.0f, curves.curves_num()))); + fill_opacities.span[active_curve] = start_opacity; + curve_attributes_to_skip.add("fill_opacity"); + fill_opacities.finish(); + } curves.curve_types_for_write()[active_curve] = CURVE_TYPE_POLY; curves.update_curve_types(); @@ -485,12 +475,10 @@ struct PaintOperationExecutor { /* Initialize the rest of the attributes with default values. */ bke::fill_attribute_range_default(attributes, bke::AttrDomain::Point, - this->skipped_attribute_ids(bke::AttrDomain::Point), + point_attributes_to_skip, IndexRange(last_active_point, 1)); - bke::fill_attribute_range_default(attributes, - bke::AttrDomain::Curve, - this->skipped_attribute_ids(bke::AttrDomain::Curve), - IndexRange(active_curve, 1)); + bke::fill_attribute_range_default( + attributes, bke::AttrDomain::Curve, curve_attributes_to_skip, IndexRange(active_curve, 1)); drawing_->tag_topology_changed(); } @@ -700,7 +688,8 @@ struct PaintOperationExecutor { /* Resize the curves geometry. */ extend_curve(curves, on_back, new_points_num); - /* Subdivide stroke in new_points. */ + Set point_attributes_to_skip; + /* Subdivide new segment. */ const IndexRange new_points = curves.points_by_curve()[active_curve].take_back(new_points_num); Array new_screen_space_coords(new_points_num); MutableSpan positions = curves.positions_for_write(); @@ -708,11 +697,13 @@ struct PaintOperationExecutor { MutableSpan new_radii = drawing_->radii_for_write().slice(new_points); MutableSpan new_opacities = drawing_->opacities_for_write().slice(new_points); linear_interpolation(prev_coords, coords, new_screen_space_coords, is_first_sample); + point_attributes_to_skip.add_multiple({"position", "radius", "opacity"}); if (vertex_color_) { MutableSpan new_vertex_colors = drawing_->vertex_colors_for_write().slice( new_points); linear_interpolation( prev_vertex_color, *vertex_color_, new_vertex_colors, is_first_sample); + point_attributes_to_skip.add("vertex_color"); } /* Randomize radii. */ @@ -784,7 +775,7 @@ struct PaintOperationExecutor { /* Initialize the rest of the attributes with default values. */ bke::fill_attribute_range_default(attributes, bke::AttrDomain::Point, - this->skipped_attribute_ids(bke::AttrDomain::Point), + point_attributes_to_skip, curves.points_range().take_back(1)); drawing_->set_texture_matrices({self.texture_space_}, IndexRange::from_single(active_curve)); @@ -853,12 +844,13 @@ void PaintOperation::on_stroke_begin(const bContext &C, const InputSample &start Material *material = BKE_grease_pencil_object_material_ensure_from_active_input_brush( CTX_data_main(&C), object, brush); const int material_index = BKE_object_material_index_get(object, material); + const bool use_fill = (material->gp_style->flag & GP_MATERIAL_FILL_SHOW) != 0; /* We're now starting to draw. */ grease_pencil->runtime->is_drawing_stroke = true; PaintOperationExecutor executor{C}; - executor.process_start_sample(*this, C, start_sample, material_index); + executor.process_start_sample(*this, C, start_sample, material_index, use_fill); DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY); WM_event_add_notifier(&C, NC_GEOM | ND_DATA, grease_pencil);