Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc29
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc3
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc47
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc4
-rw-r--r--source/blender/nodes/intern/node_common.cc138
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_curves.c5
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_output.c2
19 files changed, 173 insertions, 142 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
index 0169ead5bd2..040ebf55ec5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
@@ -19,6 +19,8 @@ static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
+ GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
+
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (!geometry_set.has_curves()) {
return;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
index ba7985f26bc..c1f631a86fa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
@@ -309,6 +309,7 @@ class SampleCurveFunction : public fn::MultiFunction {
if (curves.points_num() == 0) {
return return_default();
}
+ curves.ensure_can_interpolate_to_evaluated();
Span<float3> evaluated_positions = curves.evaluated_positions();
Span<float3> evaluated_tangents;
Span<float3> evaluated_normals;
@@ -527,29 +528,33 @@ static void node_geo_exec(GeoNodeExecParams params)
mode == GEO_NODE_CURVE_SAMPLE_FACTOR ? "Factor" : "Length");
GField src_values_field = get_input_attribute_field(params, data_type);
- auto sample_fn = std::make_unique<SampleCurveFunction>(
- std::move(geometry_set), mode, std::move(src_values_field));
-
std::shared_ptr<FieldOperation> sample_op;
if (curves.curves_num() == 1) {
- sample_op = FieldOperation::Create(std::move(sample_fn),
- {fn::make_constant_field<int>(0), std::move(length_field)});
+ sample_op = FieldOperation::Create(
+ std::make_unique<SampleCurveFunction>(
+ std::move(geometry_set), mode, std::move(src_values_field)),
+ {fn::make_constant_field<int>(0), std::move(length_field)});
}
else {
- Field<int> curve_index;
- Field<float> length_in_curve;
if (storage.use_all_curves) {
auto index_fn = std::make_unique<SampleFloatSegmentsFunction>(
curve_accumulated_lengths(curves), mode);
auto index_op = FieldOperation::Create(std::move(index_fn), {std::move(length_field)});
- curve_index = Field<int>(index_op, 0);
- length_in_curve = Field<float>(index_op, 1);
+ Field<int> curve_index = Field<int>(index_op, 0);
+ Field<float> length_in_curve = Field<float>(index_op, 1);
+ sample_op = FieldOperation::Create(
+ std::make_unique<SampleCurveFunction>(
+ std::move(geometry_set), GEO_NODE_CURVE_SAMPLE_LENGTH, std::move(src_values_field)),
+ {std::move(curve_index), std::move(length_in_curve)});
}
else {
- curve_index = params.extract_input<Field<int>>("Curve Index");
- length_in_curve = std::move(length_field);
+ Field<int> curve_index = params.extract_input<Field<int>>("Curve Index");
+ Field<float> length_in_curve = std::move(length_field);
+ sample_op = FieldOperation::Create(
+ std::make_unique<SampleCurveFunction>(
+ std::move(geometry_set), mode, std::move(src_values_field)),
+ {std::move(curve_index), std::move(length_in_curve)});
}
- sample_op = FieldOperation::Create(std::move(sample_fn), {curve_index, length_in_curve});
}
params.set_output("Position", Field<float3>(sample_op, 0));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
index 3dc89a9058e..159a4661df0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
@@ -117,9 +117,8 @@ static VArray<float> construct_curve_parameter_varray(const bke::CurvesGeometry
threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange range) {
for (const int i_curve : range) {
- const float total_length = curves.evaluated_length_total_for_curve(i_curve,
- cyclic[i_curve]);
MutableSpan<float> curve_lengths = lengths.slice(curves.points_for_curve(i_curve));
+ const float total_length = curve_lengths.last();
if (total_length > 0.0f) {
const float factor = 1.0f / total_length;
for (float &value : curve_lengths) {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc
index 4d60ab939ca..459f45ef8fb 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc
@@ -48,6 +48,11 @@ class CurveOfPointInput final : public bke::CurvesFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
class PointIndexInCurveInput final : public bke::CurvesFieldInput {
@@ -86,6 +91,11 @@ class PointIndexInCurveInput final : public bke::CurvesFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/)
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc
index 9f3d3c2caf3..7f69503831f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc
@@ -113,6 +113,11 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_CURVE;
+ }
};
class CurvePointCountInput final : public bke::CurvesFieldInput {
@@ -146,6 +151,11 @@ class CurvePointCountInput final : public bke::CurvesFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_CURVE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
index 3ec71877b7c..b0c2f3117fa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
@@ -19,6 +19,7 @@ NODE_STORAGE_FUNCS(NodeGeometryCurveTrim)
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
+ b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
b.add_input<decl::Float>(N_("Start"))
.min(0.0f)
.max(1.0f)
@@ -64,7 +65,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
const NodeGeometryCurveTrim &storage = node_storage(*node);
const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)storage.mode;
- bNodeSocket *start_fac = static_cast<bNodeSocket *>(node->inputs.first)->next;
+ bNodeSocket *start_fac = static_cast<bNodeSocket *>(node->inputs.first)->next->next;
bNodeSocket *end_fac = start_fac->next;
bNodeSocket *start_len = end_fac->next;
bNodeSocket *end_len = start_len->next;
@@ -109,6 +110,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
static void geometry_set_curve_trim(GeometrySet &geometry_set,
const GeometryNodeCurveSampleMode mode,
+ Field<bool> &selection_field,
Field<float> &start_field,
Field<float> &end_field)
{
@@ -123,41 +125,21 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set,
bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE};
fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()};
+ evaluator.add(selection_field);
evaluator.add(start_field);
evaluator.add(end_field);
evaluator.evaluate();
- const VArray<float> starts = evaluator.get_evaluated<float>(0);
- const VArray<float> ends = evaluator.get_evaluated<float>(1);
-
- const VArray<bool> cyclic = src_curves.cyclic();
-
- /* If node length input is on form [0, 1] instead of [0, length]*/
- const bool normalized_length_lookup = mode == GEO_NODE_CURVE_SAMPLE_FACTOR;
-
- /* Stack start + end field. */
- Vector<float> length_factors(src_curves.curves_num() * 2);
- Vector<int64_t> lookup_indices(src_curves.curves_num() * 2);
- threading::parallel_for(src_curves.curves_range(), 512, [&](IndexRange curve_range) {
- for (const int64_t curve_i : curve_range) {
- const bool negative_trim = !cyclic[curve_i] && starts[curve_i] > ends[curve_i];
- length_factors[curve_i] = starts[curve_i];
- length_factors[curve_i + src_curves.curves_num()] = negative_trim ? starts[curve_i] :
- ends[curve_i];
- lookup_indices[curve_i] = curve_i;
- lookup_indices[curve_i + src_curves.curves_num()] = curve_i;
- }
- });
- /* Create curve trim lookup table. */
- Array<bke::curves::CurvePoint, 12> point_lookups = geometry::lookup_curve_points(
- src_curves, length_factors, lookup_indices, normalized_length_lookup);
+ const IndexMask selection = evaluator.get_evaluated_as_mask(0);
+ const VArray<float> starts = evaluator.get_evaluated<float>(1);
+ const VArray<float> ends = evaluator.get_evaluated<float>(2);
- bke::CurvesGeometry dst_curves = geometry::trim_curves(
- src_curves,
- src_curves.curves_range().as_span(),
- point_lookups.as_span().slice(0, src_curves.curves_num()),
- point_lookups.as_span().slice(src_curves.curves_num(), src_curves.curves_num()));
+ if (selection.is_empty()) {
+ return;
+ }
+ bke::CurvesGeometry dst_curves = geometry::trim_curves(
+ src_curves, selection, starts, ends, mode);
Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves));
bke::curves_copy_parameters(src_curves_id, *dst_curves_id);
geometry_set.replace_curves(dst_curves_id);
@@ -171,18 +153,19 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
if (mode == GEO_NODE_CURVE_SAMPLE_FACTOR) {
Field<float> start_field = params.extract_input<Field<float>>("Start");
Field<float> end_field = params.extract_input<Field<float>>("End");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- geometry_set_curve_trim(geometry_set, mode, start_field, end_field);
+ geometry_set_curve_trim(geometry_set, mode, selection_field, start_field, end_field);
});
}
else if (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) {
Field<float> start_field = params.extract_input<Field<float>>("Start_001");
Field<float> end_field = params.extract_input<Field<float>>("End_001");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- geometry_set_curve_trim(geometry_set, mode, start_field, end_field);
+ geometry_set_curve_trim(geometry_set, mode, selection_field, start_field, end_field);
});
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
index 4bb4618588b..5a42949d4c8 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
@@ -56,6 +56,11 @@ class SplineCountFieldInput final : public bke::CurvesFieldInput {
{
return dynamic_cast<const SplineCountFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_CURVE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
index 7e7b0eb215f..aa27fa70e64 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
@@ -110,6 +110,11 @@ class TangentFieldInput final : public bke::CurvesFieldInput {
{
return dynamic_cast<const TangentFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc
index 94bca02640b..b464832409c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc
@@ -117,6 +117,11 @@ class CornersOfFaceInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_FACE;
+ }
};
static int get_poly_totloop(const MPoly &poly)
@@ -153,6 +158,11 @@ class CornersOfFaceCountInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_FACE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc
index 036af2d3b93..c01c4149864 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc
@@ -138,6 +138,11 @@ class CornersOfVertInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
class CornersOfVertCountInput final : public bke::MeshFieldInput {
@@ -174,6 +179,11 @@ class CornersOfVertCountInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc
index 84b560cb48a..e46061e0d65 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc
@@ -59,6 +59,11 @@ class CornerNextEdgeFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
class CornerPreviousEdgeFieldInput final : public bke::MeshFieldInput {
@@ -100,6 +105,11 @@ class CornerPreviousEdgeFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc
index f0cc191e217..7aadc15f7f8 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc
@@ -138,6 +138,11 @@ class EdgesOfVertInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
class EdgesOfVertCountInput final : public bke::MeshFieldInput {
@@ -175,6 +180,11 @@ class EdgesOfVertCountInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc
index d9f944ca11e..2cf7ed2c687 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc
@@ -85,6 +85,11 @@ class CornerIndexInFaceInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc
index 2cb9ae82fa1..ef5c9a445f2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc
@@ -86,6 +86,11 @@ class OffsetCornerInFaceFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc
index f0163fa553a..9f730367931 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc
@@ -53,6 +53,11 @@ class CornerVertFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
index d46ceac92ba..dcd910b8ad2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
@@ -24,11 +24,13 @@ static void set_resolution(bke::CurvesGeometry &curves,
MutableAttributeAccessor attributes = curves.attributes_for_write();
AttributeWriter<int> resolutions = attributes.lookup_or_add_for_write<int>("resolution",
ATTR_DOMAIN_CURVE);
+ bke::AttributeValidator validator = attributes.lookup_validator("resolution");
bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_CURVE};
fn::FieldEvaluator evaluator{field_context, curves.curves_num()};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(resolution_field, resolutions.varray);
+ evaluator.add_with_destination(validator.validate_field_if_necessary(resolution_field),
+ resolutions.varray);
evaluator.evaluate();
resolutions.finish();
diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc
index d01faeac401..975bf0c01ca 100644
--- a/source/blender/nodes/intern/node_common.cc
+++ b/source/blender/nodes/intern/node_common.cc
@@ -22,6 +22,7 @@
#include "BLT_translation.h"
#include "BKE_node.h"
+#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "RNA_types.h"
@@ -86,8 +87,6 @@ bool nodeGroupPoll(const bNodeTree *nodetree,
const bNodeTree *grouptree,
const char **r_disabled_hint)
{
- bool valid = true;
-
/* unspecified node group, generally allowed
* (if anything, should be avoided on operator level)
*/
@@ -106,11 +105,10 @@ bool nodeGroupPoll(const bNodeTree *nodetree,
if (node->typeinfo->poll_instance &&
!node->typeinfo->poll_instance(
const_cast<bNode *>(node), const_cast<bNodeTree *>(nodetree), r_disabled_hint)) {
- valid = false;
- break;
+ return false;
}
}
- return valid;
+ return true;
}
static void add_new_socket_from_interface(bNodeTree &node_tree,
@@ -381,53 +379,29 @@ void ntree_update_reroute_nodes(bNodeTree *ntree)
}
}
-static bool node_is_connected_to_output_recursive(bNodeTree *ntree, bNode *node)
+bool BKE_node_is_connected_to_output(const bNodeTree *ntree, const bNode *node)
{
- bNodeLink *link;
-
- /* avoid redundant checks, and infinite loops in case of cyclic node links */
- if (node->done) {
- return false;
- }
- node->done = 1;
-
- /* main test, done before child loop so it catches output nodes themselves as well */
- if (node->typeinfo->nclass == NODE_CLASS_OUTPUT && node->flag & NODE_DO_OUTPUT) {
- return true;
+ ntree->ensure_topology_cache();
+ Stack<const bNode *> nodes_to_check;
+ for (const bNodeSocket *socket : node->output_sockets()) {
+ for (const bNodeLink *link : socket->directly_linked_links()) {
+ nodes_to_check.push(link->tonode);
+ }
}
-
- /* test all connected nodes, first positive find is sufficient to return true */
- for (link = (bNodeLink *)ntree->links.first; link; link = link->next) {
- if (link->fromnode == node) {
- if (node_is_connected_to_output_recursive(ntree, link->tonode)) {
- return true;
+ while (!nodes_to_check.is_empty()) {
+ const bNode *next_node = nodes_to_check.pop();
+ for (const bNodeSocket *socket : next_node->output_sockets()) {
+ for (const bNodeLink *link : socket->directly_linked_links()) {
+ if (link->tonode->typeinfo->nclass == NODE_CLASS_OUTPUT &&
+ link->tonode->flag & NODE_DO_OUTPUT) {
+ return true;
+ }
+ nodes_to_check.push(link->tonode);
}
}
}
- return false;
-}
-
-bool BKE_node_is_connected_to_output(bNodeTree *ntree, bNode *node)
-{
- bNode *tnode;
- /* clear flags */
- for (tnode = (bNode *)ntree->nodes.first; tnode; tnode = tnode->next) {
- tnode->done = 0;
- }
-
- return node_is_connected_to_output_recursive(ntree, node);
-}
-
-void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree)
-{
- bNode *node;
-
- for (node = (bNode *)ntree->nodes.first; node; node = node->next) {
- if (node->id == id) {
- node->id = nullptr;
- }
- }
+ return false;
}
/** \} */
@@ -460,62 +434,53 @@ bNodeSocket *node_group_input_find_socket(bNode *node, const char *identifier)
void node_group_input_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *extsock = (bNodeSocket *)node->outputs.last;
- bNodeLink *link, *linknext, *exposelink;
/* Adding a tree socket and verifying will remove the extension socket!
* This list caches the existing links from the extension socket
- * so they can be recreated after verification.
- */
- ListBase tmplinks;
+ * so they can be recreated after verification. */
+ Vector<bNodeLink> temp_links;
/* find links from the extension socket and store them */
- BLI_listbase_clear(&tmplinks);
- for (link = (bNodeLink *)ntree->links.first; link; link = linknext) {
- linknext = link->next;
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
if (nodeLinkIsHidden(link)) {
continue;
}
if (link->fromsock == extsock) {
- bNodeLink *tlink = MEM_cnew<bNodeLink>("temporary link");
- *tlink = *link;
- BLI_addtail(&tmplinks, tlink);
-
+ temp_links.append(*link);
nodeRemLink(ntree, link);
}
}
/* find valid link to expose */
- exposelink = nullptr;
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
+ bNodeLink *exposelink = nullptr;
+ for (bNodeLink &link : temp_links) {
/* XXX Multiple sockets can be connected to the extension socket at once,
* in that case the arbitrary first link determines name and type.
* This could be improved by choosing the "best" type among all links,
* whatever that means.
*/
- if (!is_group_extension_socket(link->tonode, link->tosock)) {
- exposelink = link;
+ if (!is_group_extension_socket(link.tonode, link.tosock)) {
+ exposelink = &link;
break;
}
}
if (exposelink) {
- bNodeSocket *gsock, *newsock;
-
- gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->tonode, exposelink->tosock);
+ bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket(
+ ntree, exposelink->tonode, exposelink->tosock);
node_group_input_update(ntree, node);
- newsock = node_group_input_find_socket(node, gsock->identifier);
+ bNodeSocket *newsock = node_group_input_find_socket(node, gsock->identifier);
/* redirect links from the extension socket */
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
- bNodeLink *newlink = nodeAddLink(ntree, node, newsock, link->tonode, link->tosock);
+ for (bNodeLink &link : temp_links) {
+ bNodeLink *newlink = nodeAddLink(ntree, node, newsock, link.tonode, link.tosock);
if (newlink->tosock->flag & SOCK_MULTI_INPUT) {
- newlink->multi_input_socket_index = link->multi_input_socket_index;
+ newlink->multi_input_socket_index = link.multi_input_socket_index;
}
}
}
- BLI_freelistN(&tmplinks);
group_verify_socket_list(*ntree, *node, ntree->inputs, node->outputs, SOCK_OUT, true);
}
@@ -552,60 +517,51 @@ bNodeSocket *node_group_output_find_socket(bNode *node, const char *identifier)
void node_group_output_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *extsock = (bNodeSocket *)node->inputs.last;
- bNodeLink *link, *linknext, *exposelink;
/* Adding a tree socket and verifying will remove the extension socket!
* This list caches the existing links to the extension socket
- * so they can be recreated after verification.
- */
- ListBase tmplinks;
+ * so they can be recreated after verification. */
+ Vector<bNodeLink> temp_links;
/* find links to the extension socket and store them */
- BLI_listbase_clear(&tmplinks);
- for (link = (bNodeLink *)ntree->links.first; link; link = linknext) {
- linknext = link->next;
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
if (nodeLinkIsHidden(link)) {
continue;
}
if (link->tosock == extsock) {
- bNodeLink *tlink = MEM_cnew<bNodeLink>("temporary link");
- *tlink = *link;
- BLI_addtail(&tmplinks, tlink);
-
+ temp_links.append(*link);
nodeRemLink(ntree, link);
}
}
/* find valid link to expose */
- exposelink = nullptr;
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
+ bNodeLink *exposelink = nullptr;
+ for (bNodeLink &link : temp_links) {
/* XXX Multiple sockets can be connected to the extension socket at once,
* in that case the arbitrary first link determines name and type.
* This could be improved by choosing the "best" type among all links,
* whatever that means.
*/
- if (!is_group_extension_socket(link->fromnode, link->fromsock)) {
- exposelink = link;
+ if (!is_group_extension_socket(link.fromnode, link.fromsock)) {
+ exposelink = &link;
break;
}
}
if (exposelink) {
- bNodeSocket *gsock, *newsock;
-
/* XXX what if connecting virtual to virtual socket?? */
- gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->fromnode, exposelink->fromsock);
+ bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket(
+ ntree, exposelink->fromnode, exposelink->fromsock);
node_group_output_update(ntree, node);
- newsock = node_group_output_find_socket(node, gsock->identifier);
+ bNodeSocket *newsock = node_group_output_find_socket(node, gsock->identifier);
/* redirect links to the extension socket */
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
- nodeAddLink(ntree, link->fromnode, link->fromsock, node, newsock);
+ for (bNodeLink &link : temp_links) {
+ nodeAddLink(ntree, link.fromnode, link.fromsock, node, newsock);
}
}
- BLI_freelistN(&tmplinks);
group_verify_socket_list(*ntree, *node, ntree->outputs, node->inputs, SOCK_IN, true);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_curves.c b/source/blender/nodes/texture/nodes/node_texture_curves.c
index df75847dbe3..bdee2adb1ba 100644
--- a/source/blender/nodes/texture/nodes/node_texture_curves.c
+++ b/source/blender/nodes/texture/nodes/node_texture_curves.c
@@ -104,9 +104,8 @@ void register_node_type_tex_curve_rgb(void)
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
ntype.initfunc = rgb_init;
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
- ntype.init_exec_fn = node_initexec_curves ;
- ntype.exec_fn =rgb_exec ;
-
+ ntype.init_exec_fn = node_initexec_curves;
+ ntype.exec_fn = rgb_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_output.c b/source/blender/nodes/texture/nodes/node_texture_output.c
index 37e39dae22c..b640880ba9b 100644
--- a/source/blender/nodes/texture/nodes/node_texture_output.c
+++ b/source/blender/nodes/texture/nodes/node_texture_output.c
@@ -83,7 +83,7 @@ static void unique_name(bNode *node)
BLI_strncpy(new_name, name, sizeof(tno->name));
name = new_name;
}
- sprintf(new_name + new_len - 4, ".%03d", ++suffix);
+ BLI_sprintf(new_name + new_len - 4, ".%03d", ++suffix);
}
if (new_name[0] != '\0') {