Cleanup: Use legacy radius conversion factor constant

This moves the seemingly arbitrary value of  "1 / 2000"
into a constant variable
(`bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR`)
so that it can be used in all the places where
legacy "thickness" values need to be converted.
This also expands the explanation of the factor a bit, so it's
clearer why it is needed.
This commit is contained in:
Falk David
2024-04-26 12:48:26 +02:00
parent 863743bcb5
commit c2504eb779
5 changed files with 24 additions and 30 deletions

View File

@@ -35,6 +35,16 @@ namespace blender::bke {
namespace greasepencil {
/* Previously, Grease Pencil used a radius convention where 1 `px` = 0.001 units. This `px`
* was the brush size which would be stored in the stroke thickness and then scaled by the
* point pressure factor. Finally, the render engine would divide this thickness value by
* 2000 (we're going from a thickness to a radius, hence the factor of two) to convert back
* into blender units. With Grease Pencil 3, the radius is no longer stored in `px` space,
* but in blender units (world space) directly. Also note that there is no longer a stroke
* "thickness" attribute, the radii are directly stored on the points.
* For compatibility, legacy thickness values have to be multiplied by this factor. */
constexpr float LEGACY_RADIUS_CONVERSION_FACTOR = 1.0f / 2000.0f;
class DrawingRuntime {
public:
/**

View File

@@ -813,13 +813,7 @@ static void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
BLI_assert(points.size() == gps->totpoints);
const Span<bGPDspoint> src_points{gps->points, gps->totpoints};
/* Previously, Grease Pencil used a radius convention where 1 `px` = 0.001 units. This `px`
* was the brush size which would be stored in the stroke thickness and then scaled by the
* point pressure factor. Finally, the render engine would divide this thickness value by
* 2000 (we're going from a thickness to a radius, hence the factor of two) to convert back
* into blender units. Store the radius now directly in blender units. This makes it
* consistent with how hair curves handle the radius. */
const float stroke_thickness = float(gps->thickness) / 2000.0f;
const float stroke_thickness = float(gps->thickness) * LEGACY_RADIUS_CONVERSION_FACTOR;
MutableSpan<float3> dst_positions = positions.slice(points);
MutableSpan<float3> dst_handle_positions_left = has_bezier_stroke ?
handle_positions_left.slice(points) :
@@ -1225,21 +1219,19 @@ static void layer_adjustments_to_modifiers(ConversionData &conversion_data,
src_object_data.id,
{{".tint_color", ".color"}, {".tint_factor", ".factor"}});
/* Ensure values are divided by 2k, to match conversion done for non-animated value. */
constexpr float thickness_adjustement_factor = 1.0f / 2000.0f;
auto fcurve_convert_thickness_cb = [&](FCurve &fcurve) {
if (fcurve.bezt) {
for (uint i = 0; i < fcurve.totvert; i++) {
BezTriple &bezier_triple = fcurve.bezt[i];
bezier_triple.vec[0][1] *= thickness_adjustement_factor;
bezier_triple.vec[1][1] *= thickness_adjustement_factor;
bezier_triple.vec[2][1] *= thickness_adjustement_factor;
bezier_triple.vec[0][1] *= LEGACY_RADIUS_CONVERSION_FACTOR;
bezier_triple.vec[1][1] *= LEGACY_RADIUS_CONVERSION_FACTOR;
bezier_triple.vec[2][1] *= LEGACY_RADIUS_CONVERSION_FACTOR;
}
}
if (fcurve.fpt) {
for (uint i = 0; i < fcurve.totvert; i++) {
FPoint &fpoint = fcurve.fpt[i];
fpoint.vec[1] *= thickness_adjustement_factor;
fpoint.vec[1] *= LEGACY_RADIUS_CONVERSION_FACTOR;
}
}
fcurve.flag &= ~FCURVE_INT_VALUES;
@@ -1301,7 +1293,7 @@ static void layer_adjustments_to_modifiers(ConversionData &conversion_data,
/* Convert the "pixel" offset value into a radius value.
* GPv2 used a conversion of 1 "px" = 0.001. */
/* Note: this offset may be negative. */
const float radius_offset = float(thickness_px) * thickness_adjustement_factor;
const float radius_offset = float(thickness_px) * LEGACY_RADIUS_CONVERSION_FACTOR;
const auto offset_radius_ntree_ensure = [&](Library *owner_library) {
if (bNodeTree **ntree = conversion_data.offset_radius_ntree_by_library.lookup_ptr(

View File

@@ -1963,13 +1963,6 @@ static void versioning_nodes_dynamic_sockets_2(bNodeTree &ntree)
static void versioning_grease_pencil_stroke_radii_scaling(GreasePencil *grease_pencil)
{
using namespace blender;
/* Previously, Grease Pencil used a radius convention where 1 `px` = 0.001 units. This `px` was
* the brush size which would be stored in the stroke thickness and then scaled by the point
* pressure factor. Finally, the render engine would divide this thickness value by 2000 (we're
* going from a thickness to a radius, hence the factor of two) to convert back into blender
* units.
* Store the radius now directly in blender units. This makes it consistent with how hair curves
* handle the radius. */
for (GreasePencilDrawingBase *base : grease_pencil->drawings()) {
if (base->type != GP_DRAWING) {
continue;
@@ -1978,7 +1971,7 @@ static void versioning_grease_pencil_stroke_radii_scaling(GreasePencil *grease_p
MutableSpan<float> radii = drawing.radii_for_write();
threading::parallel_for(radii.index_range(), 8192, [&](const IndexRange range) {
for (const int i : range) {
radii[i] /= 2000.0f;
radii[i] *= bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
}
});
}

View File

@@ -525,8 +525,7 @@ GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd,
const GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
const bool is_in_front = (ob->dtx & OB_DRAW_IN_FRONT);
/* Grease Pencil 3 doesn't have this. */
const bool is_screenspace = false;
const bool override_vertcol = (pd->v3d_color_type != -1);
const bool is_vert_col_mode = (pd->v3d_color_type == V3D_SHADING_VERTEX_COLOR) ||
(ob->mode == OB_MODE_VERTEX_PAINT) || pd->is_render;
@@ -541,9 +540,9 @@ GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd,
const float vert_col_opacity = (override_vertcol) ?
(is_vert_col_mode ? pd->vertex_paint_opacity : 0.0f) :
(pd->is_render ? 1.0f : pd->vertex_paint_opacity);
/* Negate thickness sign to tag that strokes are in screen space.
* Convert to world units (by default, 1 meter = 1000 pixels). */
const float thickness_scale = (is_screenspace) ? -1.0f : 1.0f / 1000.0f;
/* Negate thickness sign to tag that strokes are in screen space (this is no longer used in
* GPv3). Convert to world units (by default, 1 meter = 1000 pixels). */
const float thickness_scale = blender::bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
/* If the layer is used as a mask (but is otherwise not visible in the render), render it with a
* opacity of 0 so that it can still mask other layers. */
const float layer_opacity = !is_used_as_mask ? grease_pencil_layer_final_opacity_get(

View File

@@ -750,9 +750,9 @@ static void grease_pencil_geom_batch_ensure(Object &object,
const float3 pos = math::transform_point(layer_space_to_object_space, positions[point_i]);
copy_v3_v3(s_vert.pos, pos);
s_vert.radius = radii[point_i] * ((end_cap == GP_STROKE_CAP_TYPE_ROUND) ? 1.0f : -1.0f);
/* Convert to legacy "pixel" space. The shader expects the values to be in this space.
* Otherwise the values will get clamped. */
s_vert.radius *= 1000.0f;
/* Convert to legacy "pixel" space. We divide here, because the shader expects the values to
* be in the `px` space rather than world space. Otherwise the values will get clamped. */
s_vert.radius /= bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
s_vert.opacity = opacities[point_i] *
((start_cap == GP_STROKE_CAP_TYPE_ROUND) ? 1.0f : -1.0f);
s_vert.point_id = verts_range[idx];