[Bf-blender-cvs] [51f6fa351d4] temp-geometry-nodes-curve-sample: Working sampling, only sampling builtin curve attributes doesn't work
Hans Goudey
noreply at git.blender.org
Mon Jul 19 03:54:28 CEST 2021
Commit: 51f6fa351d417aff102b6f819e1998a09b00b338
Author: Hans Goudey
Date: Sun Jul 18 21:54:20 2021 -0400
Branches: temp-geometry-nodes-curve-sample
https://developer.blender.org/rB51f6fa351d417aff102b6f819e1998a09b00b338
Working sampling, only sampling builtin curve attributes doesn't work
===================================================================
M source/blender/blenkernel/intern/spline_base.cc
M source/blender/makesdna/DNA_node_types.h
M source/blender/makesrna/intern/rna_nodetree.c
M source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
===================================================================
diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc
index 9652622d4a1..d07e0dfdf4a 100644
--- a/source/blender/blenkernel/intern/spline_base.cc
+++ b/source/blender/blenkernel/intern/spline_base.cc
@@ -463,17 +463,6 @@ Array<float> Spline::sample_uniform_index_factors(const int samples_size) const
return samples;
}
-#ifdef DEBUG
-static void assert_sorted_array_in_range(Span<float> data, const float min, const float max)
-{
- BLI_assert(data.first() >= min);
- for (const int i : IndexRange(1, data.size() - 1)) {
- BLI_assert(data[i] >= data[i - 1]);
- }
- BLI_assert(data.last() <= max);
-}
-#endif
-
/**
* Transform an array of sorted length parameters into index factors. The result is indices
* and factors to the next index, encoded in floats. The logic for converting from the float
@@ -486,15 +475,22 @@ static void assert_sorted_array_in_range(Span<float> data, const float min, cons
* the two loops are inverted, and obviously custom parameters are provided.
*
* \note This could have a result data argument instead of returning a span in the future.
+ *
+ * \todo Investigate running the single threaded loop over evaluated points in chunks.
*/
Array<float> Spline::sample_lengths_to_index_factors(const Span<float> parameters) const
{
+ Array<int> original_indices(parameters.size());
+ for (const int i : original_indices.index_range()) {
+ original_indices[i] = i;
+ }
+
+ std::sort(original_indices.begin(), original_indices.end(), [parameters](int a, int b) {
+ return parameters[a] > parameters[b];
+ });
+
const Span<float> lengths = this->evaluated_lengths();
const float total_length = this->length();
-#ifdef DEBUG
- // assert_sorted_array_in_range(parameters, 0.0f, this->length());
-#endif
-
Array<float> index_factors(parameters.size());
/* Store the length at the previous evaluated point in a variable so it can
@@ -502,7 +498,7 @@ Array<float> Spline::sample_lengths_to_index_factors(const Span<float> parameter
float prev_length = 0.0f;
int i_evaluated = 0;
for (const int i_sample : parameters.index_range()) {
- const float sample_length = parameters[i_sample];
+ const float sample_length = std::clamp(parameters[i_sample], 0.0f, total_length);
/* Skip over every evaluated point that fits before this sample. */
while (lengths[i_evaluated] < sample_length) {
@@ -511,7 +507,7 @@ Array<float> Spline::sample_lengths_to_index_factors(const Span<float> parameter
}
const float factor = (sample_length - prev_length) / (lengths[i_evaluated] - prev_length);
- index_factors[i_sample] = i_evaluated + factor;
+ index_factors[original_indices[i_sample]] = i_evaluated + factor;
}
return index_factors;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index e325a22a74d..17efc5fc965 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1381,7 +1381,7 @@ typedef struct NodeGeometryCurveResample {
} NodeGeometryCurveResample;
typedef struct NodeGeometryCurveSample {
- /* GeometryNodeCurveSampleMode. */
+ /* GeometryNodeCurveInterpolateMode. */
uint8_t mode;
} NodeGeometryCurveSample;
@@ -1954,11 +1954,6 @@ typedef enum GeometryNodeCurveResampleMode {
GEO_NODE_CURVE_RESAMPLE_EVALUATED = 2,
} GeometryNodeCurveResampleMode;
-typedef enum GeometryNodeCurveSampleMode {
- GEO_NODE_CURVE_SAMPLE_FACTOR = 0,
- GEO_NODE_CURVE_SAMPLE_LENGTH = 1,
-} GeometryNodeCurveSampleMode;
-
typedef enum GeometryNodeCurveInterpolateMode {
GEO_NODE_CURVE_INTERPOLATE_FACTOR = 0,
GEO_NODE_CURVE_INTERPOLATE_LENGTH = 1,
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index ce2c777b782..8f6318c9d46 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -10000,16 +10000,16 @@ static void def_geo_curve_sample(StructRNA *srna)
PropertyRNA *prop;
static EnumPropertyItem mode_items[] = {
- {GEO_NODE_CURVE_SAMPLE_FACTOR,
- "COUNT",
+ {GEO_NODE_CURVE_INTERPOLATE_FACTOR,
+ "FACTOR",
0,
- "Count",
+ "Factor",
"Choose sample points on the curve based on the portion of the total length"},
- {GEO_NODE_CURVE_SAMPLE_LENGTH,
+ {GEO_NODE_CURVE_INTERPOLATE_LENGTH,
"LENGTH",
0,
"Length",
- "Choose sample points on the curve based on the assumulated length at that point"},
+ "Choose sample points on the curve based on the accumulated length at that point"},
{0, NULL, 0, NULL, NULL},
};
@@ -10017,7 +10017,7 @@ static void def_geo_curve_sample(StructRNA *srna)
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, mode_items);
- RNA_def_property_ui_text(prop, "Mode", "How to specify the amount of samples");
+ RNA_def_property_ui_text(prop, "Mode", "How to specify the sample positions on the curve");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
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 734d17ac459..9ab89c4f428 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
@@ -57,22 +57,23 @@ static void geo_node_curve_sample_init(bNodeTree *UNUSED(tree), bNode *node)
NodeGeometryCurveSample *data = (NodeGeometryCurveSample *)MEM_callocN(
sizeof(NodeGeometryCurveSample), __func__);
- data->mode = GEO_NODE_CURVE_SAMPLE_FACTOR;
+ data->mode = GEO_NODE_CURVE_INTERPOLATE_FACTOR;
node->storage = data;
}
static void geo_node_curve_sample_update(bNodeTree *UNUSED(ntree), bNode *node)
{
const NodeGeometryCurveSample &node_storage = *(NodeGeometryCurveSample *)node->storage;
- const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)node_storage.mode;
+ const GeometryNodeCurveInterpolateMode mode = (GeometryNodeCurveInterpolateMode)
+ node_storage.mode;
bNodeSocket *parameter_socket = ((bNodeSocket *)node->inputs.first)->next;
- if (mode == GEO_NODE_CURVE_SAMPLE_FACTOR) {
+ if (mode == GEO_NODE_CURVE_INTERPOLATE_FACTOR) {
node_sock_label(parameter_socket, "Factor");
}
else {
- BLI_assert(mode == GEO_NODE_CURVE_SAMPLE_LENGTH);
+ BLI_assert(mode == GEO_NODE_CURVE_INTERPOLATE_LENGTH);
node_sock_label(parameter_socket, "Length");
}
}
@@ -103,39 +104,31 @@ static CustomDataType get_result_type(const CurveComponent &curve_component,
return curve_meta_data->data_type;
}
-using SamplePair = std::pair<GSpan, GMutableSpan>;
+struct SamplePair {
+ GSpan src;
+ GMutableSpan dst;
+};
-/** TODO: Investigate chunkifying the first part,
- * since #sample_lengths_to_index_factors is single threaded. */
-static void spline_sample_attributes(const Spline &spline,
- Span<float> lengths,
- Span<SamplePair> samples_extrapolated,
- Span<SamplePair> samples)
+static void sample_with_lookups(const SamplePair &sample, Span<Spline::LookupResult> lookups)
{
- Array<int> original_indices(lengths.size());
- for (const int i : original_indices.index_range()) {
- original_indices[i] = i;
- }
-
- std::sort(original_indices.begin(), original_indices.end(), [lengths](int a, int b) {
- return lengths[a] > lengths[b];
+ blender::attribute_math::convert_to_static_type(sample.src.type(), [&](auto dummy) {
+ using T = decltype(dummy);
+ Span<T> src = sample.src.typed<T>();
+ MutableSpan<T> dst = sample.dst.typed<T>();
+
+ threading::parallel_for(lookups.index_range(), 1024, [&](IndexRange range) {
+ for (const int i : range) {
+ dst[i] = attribute_math::mix2<T>(lookups[i].factor,
+ src[lookups[i].evaluated_index],
+ src[lookups[i].next_evaluated_index]);
+ }
+ });
});
-
- const Array<float> index_factors = spline.sample_lengths_to_index_factors(lengths);
-
- for (const SamplePair &sample : samples_extrapolated) {
- spline.sample_with_index_factors(sample.first, index_factors, sample.second);
- }
-
- /* TODO: Clamp index factors. */
-
- for (const SamplePair &sample : samples) {
- spline.sample_with_index_factors(sample.first, index_factors, sample.second);
- }
}
static void execute_on_component(GeometryComponent &component,
const CurveComponent &curve_component,
+ const GeometryNodeCurveInterpolateMode mode,
const StringRef pararameter_name,
const StringRef position_name,
const StringRef tangent_name,
@@ -145,58 +138,73 @@ static void execute_on_component(GeometryComponent &component,
{
const CurveEval &curve = *curve_component.get_for_read();
const Spline &spline = *curve.splines().first();
+ const float length = spline.length();
const AttributeDomain domain = get_result_domain(component, pararameter_name, result_name);
GVArray_Typed<float> parameters = component.attribute_get_for_read<float>(
pararameter_name, domain, 0.0f);
- VArray_Span<float> parameters_span{parameters};
- /* TODO: Multiply by length if in factor mode. */
- Vector<OutputAttribute> output_attributes;
- Vector<GVArrayPtr> owned_curve_attributes;
- Vector<SamplePair> sample_data;
- Vector<SamplePair> sample_data_extrapolated;
+ Array<Spline::LookupResult> lookups(parameters.size());
+ if (mode == GEO_NODE_CURVE_INTERPOLATE_LENGTH) {
+ threading::parallel_for(lookups.index_range(), 1024, [&](IndexRange range) {
+ for (const int i : range) {
+ lookups[i] = spline.lookup_evaluated_length(std::clamp(parameters[i], 0.0f, length));
+ }
+ });
+ }
+ else {
+ threading::parallel_for(lookups.index_range(), 1024, [&](Index
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list