BLI: refactor IndexMask for better performance and memory usage #104629

Merged
Jacques Lucke merged 254 commits from JacquesLucke/blender:index-mask-refactor into main 2023-05-24 18:11:47 +02:00
16 changed files with 196 additions and 213 deletions
Showing only changes of commit 8fa05e8c0f - Show all commits

View File

@ -154,24 +154,21 @@ static Array<Vector<int>> build_edge_to_edge_by_vert_map(const Span<MEdge> edges
Array<Vector<int>> vert_to_edge_map = bke::mesh_topology::build_vert_to_edge_map(edges,
verts_num);
threading::parallel_for(edge_mask.index_range(), 1024, [&](IndexRange range) {
for (const int edge_i : edge_mask.slice(range)) {
edge_mask.foreach_index(GrainSize(1024), [&](const int edge_i) {
Vector<int> &self_edges = map[edge_i];
const Span<int> vert_1_edges = vert_to_edge_map[edges[edge_i].v1];
const Span<int> vert_2_edges = vert_to_edge_map[edges[edge_i].v2];
Vector<int> &self_edges = map[edge_i];
const Span<int> vert_1_edges = vert_to_edge_map[edges[edge_i].v1];
const Span<int> vert_2_edges = vert_to_edge_map[edges[edge_i].v2];
self_edges.reserve(vert_1_edges.size() - 1 + vert_2_edges.size() - 1);
self_edges.reserve(vert_1_edges.size() - 1 + vert_2_edges.size() - 1);
for (const int i : vert_1_edges) {
if (i != edge_i) {
self_edges.append(i);
}
for (const int i : vert_1_edges) {
if (i != edge_i) {
self_edges.append(i);
}
for (const int i : vert_2_edges) {
if (i != edge_i) {
self_edges.append(i);
}
}
for (const int i : vert_2_edges) {
if (i != edge_i) {
self_edges.append(i);
}
}
});
@ -200,16 +197,14 @@ static Array<Vector<int>> build_face_to_face_by_edge_map(const Span<MPoly> polys
Array<Vector<int>> map(polys.size());
Array<Vector<int>> faces_by_edge = build_face_to_edge_by_loop_map(polys, loops, edges_num);
threading::parallel_for(poly_mask.index_range(), 1024, [&](IndexRange range) {
for (const int poly_i : poly_mask.slice(range)) {
const MPoly &poly = polys[poly_i];
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
const int edge_i = loop.e;
if (faces_by_edge[edge_i].size() > 1) {
for (const int neighbor : faces_by_edge[edge_i]) {
if (neighbor != poly_i) {
map[poly_i].append(neighbor);
}
poly_mask.foreach_index(GrainSize(1024), [&](const int poly_i) {
const MPoly &poly = polys[poly_i];
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
const int edge_i = loop.e;
if (faces_by_edge[edge_i].size() > 1) {
for (const int neighbor : faces_by_edge[edge_i]) {
if (neighbor != poly_i) {
map[poly_i].append(neighbor);
}
}
}

View File

@ -50,10 +50,10 @@ static void shortest_paths(const Mesh &mesh,
std::priority_queue<VertPriority, std::vector<VertPriority>, std::greater<VertPriority>> queue;
for (const int start_vert_i : end_selection) {
end_selection.foreach_index([&](const int start_vert_i) {
r_cost[start_vert_i] = 0.0f;
queue.emplace(0.0f, start_vert_i);
}
});
while (!queue.empty()) {
const float cost_i = queue.top().first;

View File

@ -150,7 +150,7 @@ class SampleMeshBarycentricFunction : public mf::MultiFunction {
using T = decltype(dummy);
const VArray<T> src_typed = source_data_->typed<T>();
MutableSpan<T> dst_typed = dst.typed<T>();
for (const int i : mask) {
mask.foreach_index([&](const int i) {
const int triangle_index = triangle_indices[i];
if (triangle_indices[i] != -1) {
dst_typed[i] = attribute_math::mix3(bary_weights[i],
@ -161,7 +161,7 @@ class SampleMeshBarycentricFunction : public mf::MultiFunction {
else {
dst_typed[i] = {};
}
}
});
});
}
@ -218,7 +218,7 @@ class ReverseUVSampleFunction : public mf::MultiFunction {
MutableSpan<float3> bary_weights = params.uninitialized_single_output_if_required<float3>(
3, "Barycentric Weights");
for (const int i : mask) {
mask.foreach_index([&](const int i) {
const ReverseUVSampler::Result result = reverse_uv_sampler_->sample(sample_uvs[i]);
if (!is_valid.is_empty()) {
is_valid[i] = result.type == ReverseUVSampler::ResultType::Ok;
@ -229,7 +229,7 @@ class ReverseUVSampleFunction : public mf::MultiFunction {
if (!bary_weights.is_empty()) {
bary_weights[i] = result.bary_weights;
}
}
});
}
private:

View File

@ -109,14 +109,11 @@ static void set_position_in_component(bke::CurvesGeometry &curves,
curves.handle_positions_right_for_write() :
curves.handle_positions_left_for_write();
threading::parallel_for(selection.index_range(), 2048, [&](IndexRange range) {
for (const int i : selection.slice(range)) {
selection.foreach_span(GrainSize(2048), [&](const auto sliced_selection) {
for (const int i : sliced_selection) {
update_handle_types_for_movement(handle_types[i], handle_types_other[i]);
}
});
threading::parallel_for(selection.index_range(), 2048, [&](IndexRange range) {
for (const int i : selection.slice(range)) {
for (const int i : sliced_selection) {
bke::curves::bezier::set_handle_position(positions[i],
HandleType(handle_types[i]),
HandleType(handle_types_other[i]),

View File

@ -35,7 +35,7 @@ static void set_normal_mode(bke::CurvesGeometry &curves,
evaluator.set_selection(selection_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
curves.normal_mode_for_write().fill_indices(selection, mode);
index_mask::masked_fill<int8_t>(curves.normal_mode_for_write(), mode, selection);
curves.tag_normals_changed();
}

View File

@ -112,12 +112,12 @@ class ColorBandFunction : public mf::MultiFunction {
1, "Color");
MutableSpan<float> alphas = params.uninitialized_single_output<float>(2, "Alpha");
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
ColorGeometry4f color;
BKE_colorband_evaluate(&color_band_, values[i], color);
colors[i] = color;
alphas[i] = color.a;
}
});
}
};

View File

@ -87,12 +87,12 @@ class CurveVecFunction : public mf::MultiFunction {
const VArray<float3> &vec_in = params.readonly_single_input<float3>(1, "Vector");
MutableSpan<float3> vec_out = params.uninitialized_single_output<float3>(2, "Vector");
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
BKE_curvemapping_evaluate3F(&cumap_, vec_out[i], vec_in[i]);
if (fac[i] != 1.0f) {
interp_v3_v3v3(vec_out[i], vec_in[i], vec_out[i], fac[i]);
}
}
});
}
};
@ -232,12 +232,12 @@ class CurveRGBFunction : public mf::MultiFunction {
MutableSpan<ColorGeometry4f> col_out = params.uninitialized_single_output<ColorGeometry4f>(
2, "Color");
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
BKE_curvemapping_evaluateRGBF(&cumap_, col_out[i], col_in[i]);
if (fac[i] != 1.0f) {
interp_v3_v3v3(col_out[i], col_in[i], col_out[i], fac[i]);
}
}
});
}
};
@ -350,12 +350,12 @@ class CurveFloatFunction : public mf::MultiFunction {
const VArray<float> &val_in = params.readonly_single_input<float>(1, "Value");
MutableSpan<float> val_out = params.uninitialized_single_output<float>(2, "Value");
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
val_out[i] = BKE_curvemapping_evaluateF(&cumap_, 0, val_in[i]);
if (fac[i] != 1.0f) {
val_out[i] = (1.0f - fac[i]) * val_in[i] + fac[i] * val_out[i];
}
}
});
}
};

View File

@ -224,7 +224,7 @@ class BrickFunction : public mf::MultiFunction {
const bool store_fac = !r_fac.is_empty();
const bool store_color = !r_color.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float2 f2 = brick(vector[i] * scale[i],
mortar_size[i],
mortar_smooth[i],
@ -256,7 +256,7 @@ class BrickFunction : public mf::MultiFunction {
if (store_fac) {
r_fac[i] = f;
}
}
});
}
};

View File

@ -74,7 +74,7 @@ class NodeTexChecker : public mf::MultiFunction {
params.uninitialized_single_output_if_required<ColorGeometry4f>(4, "Color");
MutableSpan<float> r_fac = params.uninitialized_single_output<float>(5, "Fac");
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
/* Avoid precision issues on unit coordinates. */
const float3 p = (vector[i] * scale[i] + 0.000001f) * 0.999999f;
@ -83,12 +83,11 @@ class NodeTexChecker : public mf::MultiFunction {
const int zi = abs(int(floorf(p.z)));
r_fac[i] = ((xi % 2 == yi % 2) == (zi % 2)) ? 1.0f : 0.0f;
}
});
if (!r_color.is_empty()) {
for (int64_t i : mask) {
r_color[i] = (r_fac[i] == 1.0f) ? color1[i] : color2[i];
}
mask.foreach_index(
[&](const int64_t i) { r_color[i] = (r_fac[i] == 1.0f) ? color1[i] : color2[i]; });
}
}
};

View File

@ -77,62 +77,57 @@ class GradientFunction : public mf::MultiFunction {
switch (gradient_type_) {
case SHD_BLEND_LINEAR: {
for (int64_t i : mask) {
fac[i] = vector[i].x;
}
mask.foreach_index([&](const int64_t i) { fac[i] = vector[i].x; });
break;
}
case SHD_BLEND_QUADRATIC: {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float r = std::max(vector[i].x, 0.0f);
fac[i] = r * r;
}
});
break;
}
case SHD_BLEND_EASING: {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float r = std::min(std::max(vector[i].x, 0.0f), 1.0f);
const float t = r * r;
fac[i] = (3.0f * t - 2.0f * t * r);
}
});
break;
}
case SHD_BLEND_DIAGONAL: {
for (int64_t i : mask) {
fac[i] = (vector[i].x + vector[i].y) * 0.5f;
}
mask.foreach_index([&](const int64_t i) { fac[i] = (vector[i].x + vector[i].y) * 0.5f; });
break;
}
case SHD_BLEND_RADIAL: {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
fac[i] = atan2f(vector[i].y, vector[i].x) / (M_PI * 2.0f) + 0.5f;
}
});
break;
}
case SHD_BLEND_QUADRATIC_SPHERE: {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
/* Bias a little bit for the case where input is a unit length vector,
* to get exactly zero instead of a small random value depending
* on float precision. */
const float r = std::max(0.999999f - math::length(vector[i]), 0.0f);
fac[i] = r * r;
}
});
break;
}
case SHD_BLEND_SPHERICAL: {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
/* Bias a little bit for the case where input is a unit length vector,
* to get exactly zero instead of a small random value depending
* on float precision. */
fac[i] = std::max(0.999999f - math::length(vector[i]), 0.0f);
}
});
break;
}
}
if (compute_color) {
for (int64_t i : mask) {
r_color[i] = ColorGeometry4f(fac[i], fac[i], fac[i], 1.0f);
}
mask.foreach_index(
[&](const int64_t i) { r_color[i] = ColorGeometry4f(fac[i], fac[i], fac[i], 1.0f); });
}
}
};

View File

@ -80,7 +80,7 @@ class MagicFunction : public mf::MultiFunction {
const bool compute_factor = !r_fac.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 co = vector[i] * scale[i];
const float distort = distortion[i];
float x = sinf((co[0] + co[1] + co[2]) * 5.0f);
@ -148,11 +148,11 @@ class MagicFunction : public mf::MultiFunction {
}
r_color[i] = ColorGeometry4f(0.5f - x, 0.5f - y, 0.5f - z, 1.0f);
}
});
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
r_fac[i] = (r_color[i].r + r_color[i].g + r_color[i].b) * (1.0f / 3.0f);
}
});
}
}
};

View File

@ -240,34 +240,34 @@ class MusgraveFunction : public mf::MultiFunction {
case 1: {
const VArray<float> &w = get_w(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float position = w[i] * scale[i];
r_factor[i] = noise::musgrave_multi_fractal(
position, dimension[i], lacunarity[i], detail[i]);
}
});
}
break;
}
case 2: {
const VArray<float3> &vector = get_vector(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 pxyz = vector[i] * scale[i];
const float2 position = float2(pxyz[0], pxyz[1]);
r_factor[i] = noise::musgrave_multi_fractal(
position, dimension[i], lacunarity[i], detail[i]);
}
});
}
break;
}
case 3: {
const VArray<float3> &vector = get_vector(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 position = vector[i] * scale[i];
r_factor[i] = noise::musgrave_multi_fractal(
position, dimension[i], lacunarity[i], detail[i]);
}
});
}
break;
}
@ -275,13 +275,13 @@ class MusgraveFunction : public mf::MultiFunction {
const VArray<float3> &vector = get_vector(0);
const VArray<float> &w = get_w(1);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 pxyz = vector[i] * scale[i];
const float pw = w[i] * scale[i];
const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
r_factor[i] = noise::musgrave_multi_fractal(
position, dimension[i], lacunarity[i], detail[i]);
}
});
}
break;
}
@ -297,34 +297,34 @@ class MusgraveFunction : public mf::MultiFunction {
case 1: {
const VArray<float> &w = get_w(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float position = w[i] * scale[i];
r_factor[i] = noise::musgrave_ridged_multi_fractal(
position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
}
});
}
break;
}
case 2: {
const VArray<float3> &vector = get_vector(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 pxyz = vector[i] * scale[i];
const float2 position = float2(pxyz[0], pxyz[1]);
r_factor[i] = noise::musgrave_ridged_multi_fractal(
position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
}
});
}
break;
}
case 3: {
const VArray<float3> &vector = get_vector(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 position = vector[i] * scale[i];
r_factor[i] = noise::musgrave_ridged_multi_fractal(
position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
}
});
}
break;
}
@ -332,13 +332,13 @@ class MusgraveFunction : public mf::MultiFunction {
const VArray<float3> &vector = get_vector(0);
const VArray<float> &w = get_w(1);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 pxyz = vector[i] * scale[i];
const float pw = w[i] * scale[i];
const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
r_factor[i] = noise::musgrave_ridged_multi_fractal(
position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
}
});
}
break;
}
@ -354,34 +354,34 @@ class MusgraveFunction : public mf::MultiFunction {
case 1: {
const VArray<float> &w = get_w(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float position = w[i] * scale[i];
r_factor[i] = noise::musgrave_hybrid_multi_fractal(
position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
}
});
}
break;
}
case 2: {
const VArray<float3> &vector = get_vector(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 pxyz = vector[i] * scale[i];
const float2 position = float2(pxyz[0], pxyz[1]);
r_factor[i] = noise::musgrave_hybrid_multi_fractal(
position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
}
});
}
break;
}
case 3: {
const VArray<float3> &vector = get_vector(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 position = vector[i] * scale[i];
r_factor[i] = noise::musgrave_hybrid_multi_fractal(
position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
}
});
}
break;
}
@ -389,13 +389,13 @@ class MusgraveFunction : public mf::MultiFunction {
const VArray<float3> &vector = get_vector(0);
const VArray<float> &w = get_w(1);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 pxyz = vector[i] * scale[i];
const float pw = w[i] * scale[i];
const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
r_factor[i] = noise::musgrave_hybrid_multi_fractal(
position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
}
});
}
break;
}
@ -409,34 +409,34 @@ class MusgraveFunction : public mf::MultiFunction {
case 1: {
const VArray<float> &w = get_w(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float position = w[i] * scale[i];
r_factor[i] = noise::musgrave_fBm(
position, dimension[i], lacunarity[i], detail[i]);
}
});
}
break;
}
case 2: {
const VArray<float3> &vector = get_vector(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 pxyz = vector[i] * scale[i];
const float2 position = float2(pxyz[0], pxyz[1]);
r_factor[i] = noise::musgrave_fBm(
position, dimension[i], lacunarity[i], detail[i]);
}
});
}
break;
}
case 3: {
const VArray<float3> &vector = get_vector(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 position = vector[i] * scale[i];
r_factor[i] = noise::musgrave_fBm(
position, dimension[i], lacunarity[i], detail[i]);
}
});
}
break;
}
@ -444,13 +444,13 @@ class MusgraveFunction : public mf::MultiFunction {
const VArray<float3> &vector = get_vector(0);
const VArray<float> &w = get_w(1);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 pxyz = vector[i] * scale[i];
const float pw = w[i] * scale[i];
const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
r_factor[i] = noise::musgrave_fBm(
position, dimension[i], lacunarity[i], detail[i]);
}
});
}
break;
}
@ -465,34 +465,34 @@ class MusgraveFunction : public mf::MultiFunction {
case 1: {
const VArray<float> &w = get_w(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float position = w[i] * scale[i];
r_factor[i] = noise::musgrave_hetero_terrain(
position, dimension[i], lacunarity[i], detail[i], offset[i]);
}
});
}
break;
}
case 2: {
const VArray<float3> &vector = get_vector(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 pxyz = vector[i] * scale[i];
const float2 position = float2(pxyz[0], pxyz[1]);
r_factor[i] = noise::musgrave_hetero_terrain(
position, dimension[i], lacunarity[i], detail[i], offset[i]);
}
});
}
break;
}
case 3: {
const VArray<float3> &vector = get_vector(0);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 position = vector[i] * scale[i];
r_factor[i] = noise::musgrave_hetero_terrain(
position, dimension[i], lacunarity[i], detail[i], offset[i]);
}
});
}
break;
}
@ -500,13 +500,13 @@ class MusgraveFunction : public mf::MultiFunction {
const VArray<float3> &vector = get_vector(0);
const VArray<float> &w = get_w(1);
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 pxyz = vector[i] * scale[i];
const float pw = w[i] * scale[i];
const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
r_factor[i] = noise::musgrave_hetero_terrain(
position, dimension[i], lacunarity[i], detail[i], offset[i]);
}
});
}
break;
}

View File

@ -141,57 +141,57 @@ class NoiseFunction : public mf::MultiFunction {
case 1: {
const VArray<float> &w = params.readonly_single_input<float>(0, "W");
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float position = w[i] * scale[i];
r_factor[i] = noise::perlin_fractal_distorted(
position, detail[i], roughness[i], distortion[i]);
}
});
}
if (compute_color) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float position = w[i] * scale[i];
const float3 c = noise::perlin_float3_fractal_distorted(
position, detail[i], roughness[i], distortion[i]);
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
}
});
}
break;
}
case 2: {
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float2 position = float2(vector[i] * scale[i]);
r_factor[i] = noise::perlin_fractal_distorted(
position, detail[i], roughness[i], distortion[i]);
}
});
}
if (compute_color) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float2 position = float2(vector[i] * scale[i]);
const float3 c = noise::perlin_float3_fractal_distorted(
position, detail[i], roughness[i], distortion[i]);
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
}
});
}
break;
}
case 3: {
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 position = vector[i] * scale[i];
r_factor[i] = noise::perlin_fractal_distorted(
position, detail[i], roughness[i], distortion[i]);
}
});
}
if (compute_color) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 position = vector[i] * scale[i];
const float3 c = noise::perlin_float3_fractal_distorted(
position, detail[i], roughness[i], distortion[i]);
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
}
});
}
break;
}
@ -199,17 +199,17 @@ class NoiseFunction : public mf::MultiFunction {
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
const VArray<float> &w = params.readonly_single_input<float>(1, "W");
if (compute_factor) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 position_vector = vector[i] * scale[i];
const float position_w = w[i] * scale[i];
const float4 position{
position_vector[0], position_vector[1], position_vector[2], position_w};
r_factor[i] = noise::perlin_fractal_distorted(
position, detail[i], roughness[i], distortion[i]);
}
});
}
if (compute_color) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 position_vector = vector[i] * scale[i];
const float position_w = w[i] * scale[i];
const float4 position{
@ -217,7 +217,7 @@ class NoiseFunction : public mf::MultiFunction {
const float3 c = noise::perlin_float3_fractal_distorted(
position, detail[i], roughness[i], distortion[i]);
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
}
});
}
break;
}

View File

@ -285,7 +285,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
float2 pos;
@ -303,7 +303,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
pos = math::safe_divide(pos, scale[i]);
r_position[i] = float3(pos.x, pos.y, 0.0f);
}
}
});
break;
}
case SHD_VORONOI_F2: {
@ -317,7 +317,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
float2 pos;
@ -335,7 +335,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
pos = math::safe_divide(pos, scale[i]);
r_position[i] = float3(pos.x, pos.y, 0.0f);
}
}
});
break;
}
case SHD_VORONOI_SMOOTH_F1: {
@ -350,7 +350,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
@ -370,7 +370,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
pos = math::safe_divide(pos, scale[i]);
r_position[i] = float3(pos.x, pos.y, 0.0f);
}
}
});
break;
}
}
@ -389,7 +389,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
noise::voronoi_f1(vector[i] * scale[i],
@ -405,7 +405,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
if (calc_position) {
r_position[i] = math::safe_divide(r_position[i], scale[i]);
}
}
});
break;
}
case SHD_VORONOI_F2: {
@ -419,7 +419,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
noise::voronoi_f2(vector[i] * scale[i],
@ -435,7 +435,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
if (calc_position) {
r_position[i] = math::safe_divide(r_position[i], scale[i]);
}
}
});
break;
}
case SHD_VORONOI_SMOOTH_F1: {
@ -450,7 +450,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
@ -468,7 +468,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
if (calc_position) {
r_position[i] = math::safe_divide(r_position[i], scale[i]);
}
}
});
break;
}
}
@ -490,7 +490,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
const bool calc_w = !r_w.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
float3 col;
@ -514,7 +514,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
r_w[i] = pos.w;
}
}
}
});
break;
}
case SHD_VORONOI_F2: {
@ -531,7 +531,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
const bool calc_w = !r_w.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
float3 col;
@ -555,7 +555,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
r_w[i] = pos.w;
}
}
}
});
break;
}
case SHD_VORONOI_SMOOTH_F1: {
@ -573,7 +573,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
const bool calc_w = !r_w.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
@ -599,7 +599,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction {
r_w[i] = pos.w;
}
}
}
});
break;
}
}
@ -718,7 +718,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_w = !r_w.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float p = w[i] * scale[i];
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
@ -733,7 +733,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
if (calc_w) {
r_w[i] = safe_divide(r_w[i], scale[i]);
}
}
});
break;
}
case SHD_VORONOI_F2: {
@ -746,7 +746,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_w = !r_w.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float p = w[i] * scale[i];
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
@ -761,7 +761,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
if (calc_w) {
r_w[i] = safe_divide(r_w[i], scale[i]);
}
}
});
break;
}
case SHD_VORONOI_SMOOTH_F1: {
@ -775,7 +775,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_w = !r_w.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float p = w[i] * scale[i];
const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
@ -792,7 +792,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
if (calc_w) {
r_w[i] = safe_divide(r_w[i], scale[i]);
}
}
});
break;
}
}
@ -810,7 +810,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
float2 pos;
@ -828,7 +828,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
pos = math::safe_divide(pos, scale[i]);
r_position[i] = float3(pos.x, pos.y, 0.0f);
}
}
});
break;
}
case SHD_VORONOI_F2: {
@ -841,7 +841,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
float2 pos;
@ -859,7 +859,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
pos = math::safe_divide(pos, scale[i]);
r_position[i] = float3(pos.x, pos.y, 0.0f);
}
}
});
break;
}
case SHD_VORONOI_SMOOTH_F1: {
@ -873,7 +873,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
@ -893,7 +893,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
pos = math::safe_divide(pos, scale[i]);
r_position[i] = float3(pos.x, pos.y, 0.0f);
}
}
});
break;
}
}
@ -911,7 +911,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
noise::voronoi_f1(vector[i] * scale[i],
@ -927,7 +927,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
if (calc_position) {
r_position[i] = math::safe_divide(r_position[i], scale[i]);
}
}
});
break;
}
case SHD_VORONOI_F2: {
@ -940,7 +940,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_distance = !r_distance.is_empty();
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
noise::voronoi_f2(vector[i] * scale[i],
@ -956,7 +956,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
if (calc_position) {
r_position[i] = math::safe_divide(r_position[i], scale[i]);
}
}
});
break;
}
case SHD_VORONOI_SMOOTH_F1: {
@ -971,7 +971,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
{
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
float3 col;
@ -989,7 +989,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
if (calc_position) {
r_position[i] = math::safe_divide(r_position[i], scale[i]);
}
}
});
}
break;
@ -1012,7 +1012,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
const bool calc_w = !r_w.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
float3 col;
@ -1036,7 +1036,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
r_w[i] = pos.w;
}
}
}
});
break;
}
case SHD_VORONOI_F2: {
@ -1052,7 +1052,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
const bool calc_w = !r_w.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
float3 col;
@ -1076,7 +1076,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
r_w[i] = pos.w;
}
}
}
});
break;
}
case SHD_VORONOI_SMOOTH_F1: {
@ -1093,7 +1093,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
const bool calc_color = !r_color.is_empty();
const bool calc_position = !r_position.is_empty();
const bool calc_w = !r_w.is_empty();
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
@ -1119,7 +1119,7 @@ class VoronoiMetricFunction : public mf::MultiFunction {
r_w[i] = pos.w;
}
}
}
});
break;
}
}
@ -1212,20 +1212,20 @@ class VoronoiEdgeFunction : public mf::MultiFunction {
switch (feature_) {
case SHD_VORONOI_DISTANCE_TO_EDGE: {
MutableSpan<float> r_distance = get_r_distance(param++);
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float p = w[i] * scale[i];
noise::voronoi_distance_to_edge(p, rand, &r_distance[i]);
}
});
break;
}
case SHD_VORONOI_N_SPHERE_RADIUS: {
MutableSpan<float> r_radius = get_r_radius(param++);
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float p = w[i] * scale[i];
noise::voronoi_n_sphere_radius(p, rand, &r_radius[i]);
}
});
break;
}
}
@ -1238,20 +1238,20 @@ class VoronoiEdgeFunction : public mf::MultiFunction {
switch (feature_) {
case SHD_VORONOI_DISTANCE_TO_EDGE: {
MutableSpan<float> r_distance = get_r_distance(param++);
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float2 p = float2(vector[i].x, vector[i].y) * scale[i];
noise::voronoi_distance_to_edge(p, rand, &r_distance[i]);
}
});
break;
}
case SHD_VORONOI_N_SPHERE_RADIUS: {
MutableSpan<float> r_radius = get_r_radius(param++);
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float2 p = float2(vector[i].x, vector[i].y) * scale[i];
noise::voronoi_n_sphere_radius(p, rand, &r_radius[i]);
}
});
break;
}
}
@ -1264,18 +1264,18 @@ class VoronoiEdgeFunction : public mf::MultiFunction {
switch (feature_) {
case SHD_VORONOI_DISTANCE_TO_EDGE: {
MutableSpan<float> r_distance = get_r_distance(param++);
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
noise::voronoi_distance_to_edge(vector[i] * scale[i], rand, &r_distance[i]);
}
});
break;
}
case SHD_VORONOI_N_SPHERE_RADIUS: {
MutableSpan<float> r_radius = get_r_radius(param++);
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
noise::voronoi_n_sphere_radius(vector[i] * scale[i], rand, &r_radius[i]);
}
});
break;
}
}
@ -1289,20 +1289,20 @@ class VoronoiEdgeFunction : public mf::MultiFunction {
switch (feature_) {
case SHD_VORONOI_DISTANCE_TO_EDGE: {
MutableSpan<float> r_distance = get_r_distance(param++);
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
noise::voronoi_distance_to_edge(p, rand, &r_distance[i]);
}
});
break;
}
case SHD_VORONOI_N_SPHERE_RADIUS: {
MutableSpan<float> r_radius = get_r_radius(param++);
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
noise::voronoi_n_sphere_radius(p, rand, &r_radius[i]);
}
});
break;
}
}

View File

@ -125,8 +125,7 @@ class WaveFunction : public mf::MultiFunction {
params.uninitialized_single_output_if_required<ColorGeometry4f>(7, "Color");
MutableSpan<float> r_fac = params.uninitialized_single_output<float>(8, "Fac");
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
float3 p = vector[i] * scale[i];
/* Prevent precision issues on unit coordinates. */
p = (p + 0.000001f) * 0.999999f;
@ -193,11 +192,11 @@ class WaveFunction : public mf::MultiFunction {
}
r_fac[i] = val;
}
});
if (!r_color.is_empty()) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
r_color[i] = ColorGeometry4f(r_fac[i], r_fac[i], r_fac[i], 1.0f);
}
});
}
}
};

View File

@ -114,45 +114,43 @@ class WhiteNoiseFunction : public mf::MultiFunction {
case 1: {
const VArray<float> &w = params.readonly_single_input<float>(0, "W");
if (compute_color) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 c = noise::hash_float_to_float3(w[i]);
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
}
});
}
if (compute_value) {
for (int64_t i : mask) {
r_value[i] = noise::hash_float_to_float(w[i]);
}
mask.foreach_index(
[&](const int64_t i) { r_value[i] = noise::hash_float_to_float(w[i]); });
}
break;
}
case 2: {
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
if (compute_color) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 c = noise::hash_float_to_float3(float2(vector[i].x, vector[i].y));
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
}
});
}
if (compute_value) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
r_value[i] = noise::hash_float_to_float(float2(vector[i].x, vector[i].y));
}
});
}
break;
}
case 3: {
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
if (compute_color) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 c = noise::hash_float_to_float3(vector[i]);
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
}
});
}
if (compute_value) {
for (int64_t i : mask) {
r_value[i] = noise::hash_float_to_float(vector[i]);
}
mask.foreach_index(
[&](const int64_t i) { r_value[i] = noise::hash_float_to_float(vector[i]); });
}
break;
}
@ -160,17 +158,17 @@ class WhiteNoiseFunction : public mf::MultiFunction {
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
const VArray<float> &w = params.readonly_single_input<float>(1, "W");
if (compute_color) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
const float3 c = noise::hash_float_to_float3(
float4(vector[i].x, vector[i].y, vector[i].z, w[i]));
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
}
});
}
if (compute_value) {
for (int64_t i : mask) {
mask.foreach_index([&](const int64_t i) {
r_value[i] = noise::hash_float_to_float(
float4(vector[i].x, vector[i].y, vector[i].z, w[i]));
}
});
}
break;
}