Refactor: Add CurvesGeometry::is_empty() function

Previously, some places used `curves.points_num() == 0` some other
places `curves.curves_num() == 0` to check if the geometry is empty.

Rather than having these two ways, add an `is_empty()` function
that replaces all these different checks.

Also update the curves geometry tests to use this function.

Pull Request: https://projects.blender.org/blender/blender/pulls/130168
This commit is contained in:
Falk David
2024-11-12 14:46:24 +01:00
committed by Falk David
parent 0a51b9a357
commit c8211b23c7
47 changed files with 71 additions and 59 deletions

View File

@@ -158,6 +158,11 @@ class CurvesGeometry : public ::CurvesGeometry {
* The number of curves in the data-block.
*/
int curves_num() const;
/**
* Return true if there are no curves in the geometry.
*/
bool is_empty() const;
IndexRange points_range() const;
IndexRange curves_range() const;
@@ -880,6 +885,12 @@ inline int CurvesGeometry::curves_num() const
{
return this->curve_num;
}
inline bool CurvesGeometry::is_empty() const
{
/* Each curve must have at least one point. */
BLI_assert((this->curve_num == 0) == (this->point_num == 0));
return this->curve_num == 0;
}
inline IndexRange CurvesGeometry::points_range() const
{
return IndexRange(this->points_num());

View File

@@ -1189,7 +1189,7 @@ void CurvesGeometry::transform(const float4x4 &matrix)
std::optional<Bounds<float3>> CurvesGeometry::bounds_min_max() const
{
if (this->points_num() == 0) {
if (this->is_empty()) {
return std::nullopt;
}
this->runtime->bounds_cache.ensure(

View File

@@ -33,6 +33,7 @@ TEST(curves_geometry, Empty)
{
CurvesGeometry empty(0, 0);
empty.cyclic();
EXPECT_TRUE(empty.is_empty());
EXPECT_FALSE(empty.bounds_min_max());
}
@@ -46,7 +47,7 @@ TEST(curves_geometry, Move)
CurvesGeometry other = std::move(curves);
/* The old curves should be empty, and the offsets are expected to be null. */
EXPECT_EQ(curves.points_num(), 0); /* NOLINT: bugprone-use-after-move */
EXPECT_TRUE(curves.is_empty()); /* NOLINT: bugprone-use-after-move */
EXPECT_EQ(curves.curve_offsets, nullptr); /* NOLINT: bugprone-use-after-move */
/* Just a basic check that the new curves work okay. */

View File

@@ -88,7 +88,7 @@ namespace bezier {
Array<float3> retrieve_all_positions(const bke::CurvesGeometry &curves,
const IndexMask &curves_selection)
{
if (curves.curves_num() == 0 || !curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
if (curves.is_empty() || !curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
return {};
}
const OffsetIndices points_by_curve = curves.points_by_curve();
@@ -114,7 +114,7 @@ void write_all_positions(bke::CurvesGeometry &curves,
const IndexMask &curves_selection,
const Span<float3> all_positions)
{
if (curves_selection.is_empty() || curves.curves_num() == 0 ||
if (curves_selection.is_empty() || curves.is_empty() ||
!curves.has_curve_with_type(CURVE_TYPE_BEZIER))
{
return;

View File

@@ -800,7 +800,7 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op)
CurvesGeometry &curves = curves_id->geometry.wrap();
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
continue;
}

View File

@@ -103,7 +103,7 @@ static int grease_pencil_stroke_smooth_exec(bContext *C, wmOperator *op)
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}
@@ -262,7 +262,7 @@ static int grease_pencil_stroke_simplify_exec(bContext *C, wmOperator *op)
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}
@@ -618,7 +618,7 @@ static int grease_pencil_dissolve_exec(bContext *C, wmOperator *op)
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}
@@ -2314,7 +2314,7 @@ static int grease_pencil_copy_strokes_exec(bContext *C, wmOperator *op)
const Layer &layer = grease_pencil.layer(drawing_info.layer_index);
const float4x4 layer_to_object = layer.to_object_space(*object);
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
continue;
}
if (!ed::curves::has_anything_selected(curves)) {
@@ -2975,7 +2975,7 @@ static int grease_pencil_snap_to_grid_exec(bContext *C, wmOperator * /*op*/)
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, grease_pencil);
for (const MutableDrawingInfo &drawing_info : drawings) {
bke::CurvesGeometry &curves = drawing_info.drawing.strokes_for_write();
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
continue;
}
if (!ed::curves::has_anything_selected(curves)) {
@@ -3037,7 +3037,7 @@ static int grease_pencil_snap_to_cursor_exec(bContext *C, wmOperator *op)
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, grease_pencil);
for (const MutableDrawingInfo &drawing_info : drawings) {
bke::CurvesGeometry &curves = drawing_info.drawing.strokes_for_write();
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
continue;
}
if (!ed::curves::has_anything_selected(curves)) {
@@ -3133,7 +3133,7 @@ static bool grease_pencil_snap_compute_centroid(const Scene &scene,
continue;
}
const bke::CurvesGeometry &curves = drawing_info.drawing.strokes();
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
continue;
}
if (!ed::curves::has_anything_selected(curves)) {

View File

@@ -453,7 +453,7 @@ static bool curves_geometry_is_equal(const bke::CurvesGeometry &curves_a,
{
using namespace blender::bke;
if (curves_a.points_num() == 0 && curves_b.points_num() == 0) {
if (curves_a.is_empty() && curves_b.is_empty()) {
return true;
}

View File

@@ -92,7 +92,7 @@ static bke::CurvesGeometry join_curves(const GreasePencil &src_grease_pencil,
Vector<bke::GeometrySet> src_geometries(all_src_curves.size());
for (const int src_curves_i : all_src_curves.index_range()) {
bke::CurvesGeometry src_curves = *all_src_curves[src_curves_i];
if (src_curves.curves_num() == 0) {
if (src_curves.is_empty()) {
continue;
}
const float4x4 &transform = transforms_to_apply[src_curves_i];

View File

@@ -874,7 +874,7 @@ static int select_set_mode_exec(bContext *C, wmOperator *op)
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
bke::CurvesGeometry &curves = drawing->wrap().strokes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
continue;
}

View File

@@ -109,7 +109,7 @@ static int grease_pencil_vertex_paint_brightness_contrast_exec(bContext *C, wmOp
Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, grease_pencil);
threading::parallel_for_each(drawings, [&](MutableDrawingInfo info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
return;
}
const bool changed = apply_color_operation_for_mode(
@@ -163,7 +163,7 @@ static int grease_pencil_vertex_paint_hsv_exec(bContext *C, wmOperator *op)
Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, grease_pencil);
threading::parallel_for_each(drawings, [&](MutableDrawingInfo info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
return;
}
const bool changed = apply_color_operation_for_mode(
@@ -228,7 +228,7 @@ static int grease_pencil_vertex_paint_invert_exec(bContext *C, wmOperator *op)
Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, grease_pencil);
threading::parallel_for_each(drawings, [&](MutableDrawingInfo info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
return;
}
const bool changed = apply_color_operation_for_mode(
@@ -278,7 +278,7 @@ static int grease_pencil_vertex_paint_levels_exec(bContext *C, wmOperator *op)
Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, grease_pencil);
threading::parallel_for_each(drawings, [&](MutableDrawingInfo info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
return;
}
const bool changed = apply_color_operation_for_mode(
@@ -338,7 +338,7 @@ static int grease_pencil_vertex_paint_set_exec(bContext *C, wmOperator *op)
Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, grease_pencil);
threading::parallel_for_each(drawings, [&](MutableDrawingInfo info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
return;
}
/* Create the color attributes if they don't exist. */
@@ -396,7 +396,7 @@ static int grease_pencil_vertex_paint_reset_exec(bContext *C, wmOperator *op)
Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, grease_pencil);
threading::parallel_for_each(drawings, [&](MutableDrawingInfo info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
return;
}
/* Remove the color attributes. */

View File

@@ -114,7 +114,7 @@ struct CombOperationExecutor {
curves_ob_orig_ = CTX_data_active_object(&C);
curves_id_orig_ = static_cast<Curves *>(curves_ob_orig_->data);
curves_orig_ = &curves_id_orig_->geometry.wrap();
if (curves_orig_->curves_num() == 0) {
if (curves_orig_->is_empty()) {
return;
}

View File

@@ -534,7 +534,7 @@ struct DensitySubtractOperationExecutor {
curves_id_ = static_cast<Curves *>(object_->data);
curves_ = &curves_id_->geometry.wrap();
if (curves_->curves_num() == 0) {
if (curves_->is_empty()) {
return;
}

View File

@@ -268,7 +268,7 @@ struct CurvesEffectOperationExecutor {
curves_id_ = static_cast<Curves *>(object_->data);
curves_ = &curves_id_->geometry.wrap();
if (curves_->curves_num() == 0) {
if (curves_->is_empty()) {
return;
}

View File

@@ -90,7 +90,7 @@ struct PinchOperationExecutor {
object_ = CTX_data_active_object(&C);
curves_id_ = static_cast<Curves *>(object_->data);
curves_ = &curves_id_->geometry.wrap();
if (curves_->curves_num() == 0) {
if (curves_->is_empty()) {
return;
}

View File

@@ -88,7 +88,7 @@ struct PuffOperationExecutor {
object_ = CTX_data_active_object(&C);
curves_id_ = static_cast<Curves *>(object_->data);
curves_ = &curves_id_->geometry.wrap();
if (curves_->curves_num() == 0) {
if (curves_->is_empty()) {
return;
}
if (curves_id_->surface == nullptr || curves_id_->surface->type != OB_MESH) {

View File

@@ -87,7 +87,7 @@ struct SelectionPaintOperationExecutor {
curves_id_ = static_cast<Curves *>(object_->data);
curves_ = &curves_id_->geometry.wrap();
if (curves_->curves_num() == 0) {
if (curves_->is_empty()) {
return;
}
selection_ = float_selection_ensure(*curves_id_);

View File

@@ -133,7 +133,7 @@ struct SlideOperationExecutor {
report_missing_surface(stroke_extension.reports);
return;
}
if (curves_orig_->curves_num() == 0) {
if (curves_orig_->is_empty()) {
return;
}
if (curves_id_orig_->surface_uv_map == nullptr) {

View File

@@ -69,7 +69,7 @@ struct SmoothOperationExecutor {
object_ = CTX_data_active_object(&C);
curves_id_ = static_cast<Curves *>(object_->data);
curves_ = &curves_id_->geometry.wrap();
if (curves_->curves_num() == 0) {
if (curves_->is_empty()) {
return;
}

View File

@@ -114,7 +114,7 @@ struct SnakeHookOperatorExecutor {
curves_id_ = static_cast<Curves *>(object_->data);
curves_ = &curves_id_->geometry.wrap();
if (curves_->curves_num() == 0) {
if (curves_->is_empty()) {
return;
}

View File

@@ -1283,7 +1283,7 @@ static Vector<FillToolTargetInfo> ensure_editable_drawings(const Scene &scene,
static void smooth_fill_strokes(bke::CurvesGeometry &curves, const IndexMask &stroke_mask)
{
const int iterations = 20;
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}
if (stroke_mask.is_empty()) {

View File

@@ -1200,7 +1200,7 @@ static void trim_stroke_ends(bke::greasepencil::Drawing &drawing,
true);
/* No intersection found. */
if (stroke_trimmed.points_num() == 0) {
if (stroke_trimmed.is_empty()) {
return;
}

View File

@@ -1073,7 +1073,7 @@ bool ED_view3d_minmax_verts(const Scene *scene, Object *obedit, float r_min[3],
greasepencil::retrieve_editable_drawings(*scene, grease_pencil);
for (const greasepencil::MutableDrawingInfo info : drawings) {
const bke::CurvesGeometry &curves = info.drawing.strokes();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
continue;
}

View File

@@ -286,7 +286,7 @@ void interpolate_curves(const CurvesGeometry &from_curves,
BLI_assert(from_curve_indices.size() == dst_curve_mask.size());
BLI_assert(to_curve_indices.size() == dst_curve_mask.size());
if (from_curves.curves_num() == 0 || to_curves.curves_num() == 0) {
if (from_curves.is_empty() || to_curves.is_empty()) {
return;
}

View File

@@ -22,7 +22,7 @@ static bke::CurvesGeometry join_curves(const GreasePencil &src_grease_pencil,
Vector<bke::GeometrySet> src_geometries(all_src_curves.size());
for (const int src_curves_i : all_src_curves.index_range()) {
bke::CurvesGeometry src_curves = *all_src_curves[src_curves_i];
if (src_curves.curves_num() == 0) {
if (src_curves.is_empty()) {
continue;
}
const float4x4 &transform = transforms_to_apply[src_curves_i];

View File

@@ -216,7 +216,7 @@ void separate_geometry(bke::GeometrySet &geometry_set,
std::optional<bke::CurvesGeometry> dst_curves = separate_curves_selection(
src_curves, field_context, selection, domain, attribute_filter);
if (dst_curves) {
if (dst_curves->points_num() == 0) {
if (dst_curves->is_empty()) {
geometry_set.remove<bke::CurveComponent>();
}
else {

View File

@@ -273,7 +273,7 @@ bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves,
const VArray<int> &cuts,
const bke::AttributeFilter &attribute_filter)
{
if (src_curves.points_num() == 0) {
if (src_curves.is_empty()) {
return src_curves;
}

View File

@@ -110,7 +110,7 @@ void ABCCurveWriter::do_write(HierarchyContext &context)
}
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}

View File

@@ -490,7 +490,7 @@ void USDCurvesWriter::do_write(HierarchyContext &context)
}
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}

View File

@@ -561,7 +561,7 @@ static void build_drawing(const GreasePencilBuildModifierData &mmd,
modifier::greasepencil::ensure_no_bezier_curves(drawing);
bke::CurvesGeometry &curves = drawing.strokes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}

View File

@@ -157,7 +157,7 @@ static void deform_drawing(const ModifierData &md,
modifier::greasepencil::ensure_no_bezier_curves(drawing);
bke::CurvesGeometry &curves = drawing.strokes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}
IndexMaskMemory memory;

View File

@@ -113,7 +113,7 @@ static void deform_drawing(const ModifierData &md,
modifier::greasepencil::ensure_no_bezier_curves(drawing);
bke::CurvesGeometry &curves = drawing.strokes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}

View File

@@ -101,7 +101,7 @@ static void deform_drawing(const GreasePencilNoiseModifierData &mmd,
modifier::greasepencil::ensure_no_bezier_curves(drawing);
bke::CurvesGeometry &strokes = drawing.strokes_for_write();
bke::MutableAttributeAccessor attributes = strokes.attributes_for_write();
if (strokes.points_num() == 0) {
if (strokes.is_empty()) {
return;
}

View File

@@ -111,7 +111,7 @@ static void deform_drawing(const ModifierData &md,
modifier::greasepencil::ensure_no_bezier_curves(drawing);
bke::CurvesGeometry &curves = drawing.strokes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}

View File

@@ -90,7 +90,7 @@ static void deform_drawing(const ModifierData &md,
const auto &mmd = reinterpret_cast<const GreasePencilThickModifierData &>(md);
bke::CurvesGeometry &curves = drawing.strokes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}

View File

@@ -128,7 +128,7 @@ static void write_weights_for_drawing(const ModifierData &md,
{
const auto &mmd = reinterpret_cast<const GreasePencilWeightAngleModifierData &>(md);
bke::CurvesGeometry &curves = drawing.strokes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}
IndexMaskMemory memory;

View File

@@ -155,7 +155,7 @@ static void write_weights_for_drawing(const ModifierData &md,
{
const auto &mmd = reinterpret_cast<const GreasePencilWeightProximityModifierData &>(md);
bke::CurvesGeometry &curves = drawing.strokes_for_write();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}
IndexMaskMemory memory;

View File

@@ -53,7 +53,7 @@ class EndpointFieldInput final : public bke::GeometryFieldInput {
return {};
}
const bke::CurvesGeometry &curves = *curves_ptr;
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return {};
}

View File

@@ -271,7 +271,7 @@ static void curve_fill_calculate(GeometrySet &geometry_set,
continue;
}
const bke::CurvesGeometry &src_curves = drawing->strokes();
if (src_curves.curves_num() == 0) {
if (src_curves.is_empty()) {
continue;
}
const Array<meshintersect::CDT_result<double>> results = do_group_aware_cdt(

View File

@@ -108,7 +108,7 @@ static void fillet_grease_pencil(GreasePencil &grease_pencil,
continue;
}
const bke::CurvesGeometry &src_curves = drawing->strokes();
if (src_curves.points_num() == 0) {
if (src_curves.is_empty()) {
continue;
}
const bke::GreasePencilLayerFieldContext field_context(

View File

@@ -267,7 +267,7 @@ class SampleCurveFunction : public mf::MultiFunction {
const Curves &curves_id = *geometry_set_.get_curves();
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return return_default();
}
curves.ensure_can_interpolate_to_evaluated();
@@ -441,7 +441,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const Curves &curves_id = *geometry_set.get_curves();
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
params.set_default_remaining_outputs();
return;
}

View File

@@ -127,7 +127,7 @@ static bool trim_curves(const bke::CurvesGeometry &src_curves,
const AttributeFilter &attribute_filter,
bke::CurvesGeometry &dst_curves)
{
if (src_curves.curves_num() == 0) {
if (src_curves.is_empty()) {
return false;
}
fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()};

View File

@@ -731,7 +731,7 @@ static bke::CurvesGeometry duplicate_points_CurvesGeometry(
const IndexAttributes &attribute_outputs,
const AttributeFilter &attribute_filter)
{
if (src_curves.points_num() == 0) {
if (src_curves.is_empty()) {
return {};
}

View File

@@ -234,7 +234,7 @@ static void node_geo_exec(GeoNodeExecParams params)
continue;
}
const bke::CurvesGeometry &src_curves = drawing->strokes();
if (src_curves.curves_num() == 0) {
if (src_curves.is_empty()) {
/* Add an empty reference so the number of layers and instances match.
* This makes it easy to reconstruct the layers afterwards and keep their attributes.
* Although in this particular case we don't propagate the attributes. */

View File

@@ -89,7 +89,7 @@ static void set_position_in_component(Curves &curves_id,
const Field<float3> &offset_field)
{
bke::CurvesGeometry &curves = curves_id.geometry.wrap();
if (curves.points_num() == 0) {
if (curves.is_empty()) {
return;
}

View File

@@ -120,7 +120,7 @@ static void node_geo_exec(GeoNodeExecParams params)
continue;
}
bke::CurvesGeometry &curves = drawing->strokes_for_write();
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
continue;
}

View File

@@ -83,7 +83,7 @@ static void set_position_in_grease_pencil(GreasePencil &grease_pencil,
using namespace blender::bke::greasepencil;
for (const int layer_index : grease_pencil.layers().index_range()) {
Drawing *drawing = grease_pencil.get_eval_drawing(grease_pencil.layer(layer_index));
if (drawing == nullptr || drawing->strokes().points_num() == 0) {
if (drawing == nullptr || drawing->strokes().is_empty()) {
continue;
}
set_curves_position(

View File

@@ -442,7 +442,7 @@ class LazyFunctionForForeachGeometryElementZone : public LazyFunction {
continue;
}
const bke::CurvesGeometry &curves = drawing->strokes();
if (curves.curves_num() == 0) {
if (curves.is_empty()) {
continue;
}
component_ids.append({component_type, iteration_domain, layer_i});