diff --git a/source/blender/blenkernel/BKE_grease_pencil.hh b/source/blender/blenkernel/BKE_grease_pencil.hh index e6100d2be7f..1c07b49ad14 100644 --- a/source/blender/blenkernel/BKE_grease_pencil.hh +++ b/source/blender/blenkernel/BKE_grease_pencil.hh @@ -14,6 +14,7 @@ #include "BLI_math_vector_types.hh" #include "BLI_shared_cache.hh" #include "BLI_utility_mixins.hh" +#include "BLI_virtual_array.hh" #include "DNA_gpencil_legacy_types.h" #include "DNA_grease_pencil_types.h" @@ -76,6 +77,19 @@ class Drawing : public ::GreasePencilDrawing { */ Span triangles() const; void tag_positions_changed(); + + /** + * Radii of the points. Values are expected to be in blender units. + */ + VArray radii() const; + MutableSpan radii_for_write(); + + /** + * Opacities for the points. Used by the render engine as an alpha value so they are expected to + * be between 0 and 1 inclusive. + */ + VArray opacities() const; + MutableSpan opacities_for_write(); }; class LayerGroup; diff --git a/source/blender/blenkernel/intern/grease_pencil.cc b/source/blender/blenkernel/intern/grease_pencil.cc index c4b8a9d968d..1160ea0f28e 100644 --- a/source/blender/blenkernel/intern/grease_pencil.cc +++ b/source/blender/blenkernel/intern/grease_pencil.cc @@ -29,6 +29,7 @@ #include "BLI_string_ref.hh" #include "BLI_string_utils.h" #include "BLI_vector_set.hh" +#include "BLI_virtual_array.hh" #include "BLO_read_write.h" @@ -250,6 +251,40 @@ IDTypeInfo IDType_ID_GP = { namespace blender::bke::greasepencil { +static const std::string ATTR_OPACITY = "opacity"; +static const std::string ATTR_RADIUS = "radius"; + +/* Curves attributes getters */ +static int domain_num(const CurvesGeometry &curves, const eAttrDomain domain) +{ + return domain == ATTR_DOMAIN_POINT ? curves.points_num() : curves.curves_num(); +} +static CustomData &domain_custom_data(CurvesGeometry &curves, const eAttrDomain domain) +{ + return domain == ATTR_DOMAIN_POINT ? curves.point_data : curves.curve_data; +} +template +static MutableSpan get_mutable_attribute(CurvesGeometry &curves, + const eAttrDomain domain, + const StringRefNull name, + const T default_value = T()) +{ + const int num = domain_num(curves, domain); + const eCustomDataType type = cpp_type_to_custom_data_type(CPPType::get()); + CustomData &custom_data = domain_custom_data(curves, domain); + + T *data = (T *)CustomData_get_layer_named_for_write(&custom_data, type, name.c_str(), num); + if (data != nullptr) { + return {data, num}; + } + data = (T *)CustomData_add_layer_named(&custom_data, type, CD_SET_DEFAULT, num, name.c_str()); + MutableSpan span = {data, num}; + if (num > 0 && span.first() != default_value) { + span.fill(default_value); + } + return span; +} + Drawing::Drawing() { this->base.type = GP_DRAWING; @@ -344,6 +379,30 @@ bke::CurvesGeometry &Drawing::strokes_for_write() return this->geometry.wrap(); } +VArray Drawing::radii() const +{ + return *this->strokes().attributes().lookup_or_default( + ATTR_RADIUS, ATTR_DOMAIN_POINT, 0.01f); +} + +MutableSpan Drawing::radii_for_write() +{ + return get_mutable_attribute( + this->geometry.wrap(), ATTR_DOMAIN_POINT, ATTR_RADIUS, 0.01f); +} + +VArray Drawing::opacities() const +{ + return *this->strokes().attributes().lookup_or_default( + ATTR_OPACITY, ATTR_DOMAIN_POINT, 1.0f); +} + +MutableSpan Drawing::opacities_for_write() +{ + return get_mutable_attribute( + this->geometry.wrap(), ATTR_DOMAIN_POINT, ATTR_OPACITY, 1.0f); +} + void Drawing::tag_positions_changed() { this->geometry.wrap().tag_positions_changed(); diff --git a/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc b/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc index 115a7b8ea08..7bd5c56f059 100644 --- a/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc +++ b/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc @@ -40,7 +40,8 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf, } /* Resize the CurvesGeometry. */ - CurvesGeometry &curves = r_drawing.geometry.wrap(); + Drawing &drawing = r_drawing.wrap(); + CurvesGeometry &curves = drawing.strokes_for_write(); curves.resize(num_points, num_strokes); if (num_strokes > 0) { curves.offsets_for_write().copy_from(offsets); @@ -53,10 +54,8 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf, /* Point Attributes. */ MutableSpan positions = curves.positions_for_write(); - SpanAttributeWriter radii = attributes.lookup_or_add_for_write_span( - "radius", ATTR_DOMAIN_POINT); - SpanAttributeWriter opacities = attributes.lookup_or_add_for_write_span( - "opacity", ATTR_DOMAIN_POINT); + MutableSpan radii = drawing.radii_for_write(); + MutableSpan opacities = drawing.opacities_for_write(); SpanAttributeWriter delta_times = attributes.lookup_or_add_for_write_span( "delta_time", ATTR_DOMAIN_POINT); SpanAttributeWriter rotations = attributes.lookup_or_add_for_write_span( @@ -118,8 +117,8 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf, Span stroke_points{gps->points, gps->totpoints}; MutableSpan stroke_positions = positions.slice(stroke_points_range); - MutableSpan stroke_radii = radii.span.slice(stroke_points_range); - MutableSpan stroke_opacities = opacities.span.slice(stroke_points_range); + MutableSpan stroke_radii = radii.slice(stroke_points_range); + MutableSpan stroke_opacities = opacities.slice(stroke_points_range); MutableSpan stroke_deltatimes = delta_times.span.slice(stroke_points_range); MutableSpan stroke_rotations = rotations.span.slice(stroke_points_range); MutableSpan stroke_vertex_colors = vertex_colors.span.slice( @@ -153,8 +152,6 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf, } } - radii.finish(); - opacities.finish(); delta_times.finish(); rotations.finish(); vertex_colors.finish(); diff --git a/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc b/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc index a8db94bf0ac..272e31b346f 100644 --- a/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc +++ b/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc @@ -315,10 +315,8 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr const OffsetIndices points_by_curve = curves.points_by_curve(); const Span positions = curves.positions(); const VArray cyclic = curves.cyclic(); - const VArray radii = *attributes.lookup_or_default( - "radius", ATTR_DOMAIN_POINT, 1.0f); - const VArray opacities = *attributes.lookup_or_default( - "opacity", ATTR_DOMAIN_POINT, 1.0f); + const VArray radii = drawing.radii(); + const VArray opacities = drawing.opacities(); /* Assumes that if the ".selection" attribute does not exist, all points are selected. */ const VArray selection_float = *attributes.lookup_or_default( ".selection", ATTR_DOMAIN_POINT, true); diff --git a/source/blender/editors/sculpt_paint/grease_pencil_paint.cc b/source/blender/editors/sculpt_paint/grease_pencil_paint.cc index fd0f6fd3fde..846764b7406 100644 --- a/source/blender/editors/sculpt_paint/grease_pencil_paint.cc +++ b/source/blender/editors/sculpt_paint/grease_pencil_paint.cc @@ -91,7 +91,7 @@ void PaintOperation::on_stroke_done(const bContext &C) const Span stroke_points = grease_pencil_eval.runtime->stroke_buffer(); - CurvesGeometry &curves = drawing_orig.geometry.wrap(); + CurvesGeometry &curves = drawing_orig.strokes_for_write(); int num_old_curves = curves.curves_num(); int num_old_points = curves.points_num(); @@ -107,16 +107,14 @@ void PaintOperation::on_stroke_done(const bContext &C) /* Set position, radius and opacity attribute. */ bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); MutableSpan positions = curves.positions_for_write(); - SpanAttributeWriter radii = attributes.lookup_or_add_for_write_span( - "radius", ATTR_DOMAIN_POINT); - SpanAttributeWriter opacities = attributes.lookup_or_add_for_write_span( - "opacity", ATTR_DOMAIN_POINT); + MutableSpan radii = drawing_orig.radii_for_write(); + MutableSpan opacities = drawing_orig.opacities_for_write(); for (const int i : IndexRange(stroke_points.size())) { const bke::greasepencil::StrokePoint &point = stroke_points[i]; const int point_i = new_points_range[i]; positions[point_i] = point.position; - radii.span[point_i] = point.radius; - opacities.span[point_i] = point.opacity; + radii[point_i] = point.radius; + opacities[point_i] = point.opacity; } /* Set material index attribute. */ @@ -149,8 +147,6 @@ void PaintOperation::on_stroke_done(const bContext &C) grease_pencil_eval.runtime->stroke_cache.clear(); drawing_orig.tag_positions_changed(); - radii.finish(); - opacities.finish(); materials.finish(); DEG_id_tag_update(&grease_pencil_orig.id, ID_RECALC_GEOMETRY);