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 0f9c14b0fee..8d9e4a07a76 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 @@ -49,6 +49,8 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput { const eAttrDomain domain, const IndexMask mask) const final { + const OffsetIndices points_by_curve = curves.points_by_curve(); + const bke::CurvesFieldContext context{curves, domain}; fn::FieldEvaluator evaluator{context, &mask}; evaluator.add(curve_index_); @@ -62,7 +64,7 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput { point_evaluator.add(sort_weight_); point_evaluator.evaluate(); const VArray all_sort_weights = point_evaluator.get_evaluated(0); - const OffsetIndices points_by_curve = curves.points_by_curve(); + const bool use_sorting = !all_sort_weights.is_single(); Array point_of_curve(mask.min_array_size()); threading::parallel_for(mask.index_range(), 256, [&](const IndexRange range) { @@ -77,25 +79,29 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput { point_of_curve[selection_i] = 0; continue; } - const IndexRange points = points_by_curve[curve_i]; - /* Retrieve the weights for each point. */ - sort_weights.reinitialize(points.size()); - all_sort_weights.materialize_compressed(IndexMask(points), sort_weights.as_mutable_span()); - - /* Sort a separate array of compressed indices corresponding to the compressed weights. - * This allows using `materialize_compressed` to avoid virtual function call overhead - * when accessing values in the sort weights. However, it means a separate array of - * indices within the compressed array is necessary for sorting. */ - sort_indices.reinitialize(points.size()); - std::iota(sort_indices.begin(), sort_indices.end(), 0); - std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { - return sort_weights[a] < sort_weights[b]; - }); - const int index_in_sort_wrapped = mod_i(index_in_sort, points.size()); - point_of_curve[selection_i] = points[sort_indices[index_in_sort_wrapped]]; + if (use_sorting) { + /* Retrieve the weights for each point. */ + sort_weights.reinitialize(points.size()); + all_sort_weights.materialize_compressed(IndexMask(points), + sort_weights.as_mutable_span()); + + /* Sort a separate array of compressed indices corresponding to the compressed weights. + * This allows using `materialize_compressed` to avoid virtual function call overhead + * when accessing values in the sort weights. However, it means a separate array of + * indices within the compressed array is necessary for sorting. */ + sort_indices.reinitialize(points.size()); + std::iota(sort_indices.begin(), sort_indices.end(), 0); + std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { + return sort_weights[a] < sort_weights[b]; + }); + point_of_curve[selection_i] = points[sort_indices[index_in_sort_wrapped]]; + } + else { + point_of_curve[selection_i] = points[index_in_sort_wrapped]; + } } }); 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 d5b4b4869c1..55c70095236 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 @@ -64,6 +64,7 @@ class CornersOfFaceInput final : public bke::MeshFieldInput { corner_evaluator.add(sort_weight_); corner_evaluator.evaluate(); const VArray all_sort_weights = corner_evaluator.get_evaluated(0); + const bool use_sorting = !all_sort_weights.is_single(); Array corner_of_face(mask.min_array_size()); threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) { @@ -82,23 +83,27 @@ class CornersOfFaceInput final : public bke::MeshFieldInput { const MPoly &poly = polys[poly_i]; const IndexRange corners(poly.loopstart, poly.totloop); - /* Retrieve the weights for each corner. */ - sort_weights.reinitialize(corners.size()); - all_sort_weights.materialize_compressed(IndexMask(corners), - sort_weights.as_mutable_span()); - - /* Sort a separate array of compressed indices corresponding to the compressed weights. - * This allows using `materialize_compressed` to avoid virtual function call overhead - * when accessing values in the sort weights. However, it means a separate array of - * indices within the compressed array is necessary for sorting. */ - sort_indices.reinitialize(corners.size()); - std::iota(sort_indices.begin(), sort_indices.end(), 0); - std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { - return sort_weights[a] < sort_weights[b]; - }); - const int index_in_sort_wrapped = mod_i(index_in_sort, corners.size()); - corner_of_face[selection_i] = corners[sort_indices[index_in_sort_wrapped]]; + if (use_sorting) { + /* Retrieve the weights for each corner. */ + sort_weights.reinitialize(corners.size()); + all_sort_weights.materialize_compressed(IndexMask(corners), + sort_weights.as_mutable_span()); + + /* Sort a separate array of compressed indices corresponding to the compressed weights. + * This allows using `materialize_compressed` to avoid virtual function call overhead + * when accessing values in the sort weights. However, it means a separate array of + * indices within the compressed array is necessary for sorting. */ + sort_indices.reinitialize(corners.size()); + std::iota(sort_indices.begin(), sort_indices.end(), 0); + std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { + return sort_weights[a] < sort_weights[b]; + }); + corner_of_face[selection_i] = corners[sort_indices[index_in_sort_wrapped]]; + } + else { + corner_of_face[selection_i] = corners[index_in_sort_wrapped]; + } } }); 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 12310d6df15..8d7ebb4e105 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 @@ -77,6 +77,7 @@ class CornersOfVertInput final : public bke::MeshFieldInput { corner_evaluator.add(sort_weight_); corner_evaluator.evaluate(); const VArray all_sort_weights = corner_evaluator.get_evaluated(0); + const bool use_sorting = !all_sort_weights.is_single(); Array corner_of_vertex(mask.min_array_size()); threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) { @@ -99,27 +100,31 @@ class CornersOfVertInput final : public bke::MeshFieldInput { continue; } - /* Retrieve the connected edge indices as 64 bit integers for #materialize_compressed. */ - corner_indices.reinitialize(corners.size()); - convert_span(corners, corner_indices); - - /* Retrieve a compressed array of weights for each edge. */ - sort_weights.reinitialize(corners.size()); - all_sort_weights.materialize_compressed(IndexMask(corner_indices), - sort_weights.as_mutable_span()); - - /* Sort a separate array of compressed indices corresponding to the compressed weights. - * This allows using `materialize_compressed` to avoid virtual function call overhead - * when accessing values in the sort weights. However, it means a separate array of - * indices within the compressed array is necessary for sorting. */ - sort_indices.reinitialize(corners.size()); - std::iota(sort_indices.begin(), sort_indices.end(), 0); - std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { - return sort_weights[a] < sort_weights[b]; - }); - const int index_in_sort_wrapped = mod_i(index_in_sort, corners.size()); - corner_of_vertex[selection_i] = corner_indices[sort_indices[index_in_sort_wrapped]]; + if (use_sorting) { + /* Retrieve the connected edge indices as 64 bit integers for #materialize_compressed. */ + corner_indices.reinitialize(corners.size()); + convert_span(corners, corner_indices); + + /* Retrieve a compressed array of weights for each edge. */ + sort_weights.reinitialize(corners.size()); + all_sort_weights.materialize_compressed(IndexMask(corner_indices), + sort_weights.as_mutable_span()); + + /* Sort a separate array of compressed indices corresponding to the compressed weights. + * This allows using `materialize_compressed` to avoid virtual function call overhead + * when accessing values in the sort weights. However, it means a separate array of + * indices within the compressed array is necessary for sorting. */ + sort_indices.reinitialize(corners.size()); + std::iota(sort_indices.begin(), sort_indices.end(), 0); + std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { + return sort_weights[a] < sort_weights[b]; + }); + corner_of_vertex[selection_i] = corner_indices[sort_indices[index_in_sort_wrapped]]; + } + else { + corner_of_vertex[selection_i] = corner_indices[index_in_sort_wrapped]; + } } }); 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 b16bbabfe0b..7c27a4b783d 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 @@ -61,8 +61,8 @@ class EdgesOfVertInput final : public bke::MeshFieldInput { { const IndexRange vert_range(mesh.totvert); const Span edges = mesh.edges(); - Array> vert_to_edge_map = bke::mesh_topology::build_vert_to_edge_map(edges, - mesh.totvert); + const Array> vert_to_edge_map = bke::mesh_topology::build_vert_to_edge_map( + edges, mesh.totvert); const bke::MeshFieldContext context{mesh, domain}; fn::FieldEvaluator evaluator{context, &mask}; @@ -77,6 +77,7 @@ class EdgesOfVertInput final : public bke::MeshFieldInput { edge_evaluator.add(sort_weight_); edge_evaluator.evaluate(); const VArray all_sort_weights = edge_evaluator.get_evaluated(0); + const bool use_sorting = !all_sort_weights.is_single(); Array edge_of_vertex(mask.min_array_size()); threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) { @@ -99,27 +100,32 @@ class EdgesOfVertInput final : public bke::MeshFieldInput { continue; } - /* Retrieve the connected edge indices as 64 bit integers for #materialize_compressed. */ - edge_indices.reinitialize(edges.size()); - convert_span(edges, edge_indices); - - /* Retrieve a compressed array of weights for each edge. */ - sort_weights.reinitialize(edges.size()); - all_sort_weights.materialize_compressed(IndexMask(edge_indices), - sort_weights.as_mutable_span()); - - /* Sort a separate array of compressed indices corresponding to the compressed weights. - * This allows using `materialize_compressed` to avoid virtual function call overhead - * when accessing values in the sort weights. However, it means a separate array of - * indices within the compressed array is necessary for sorting. */ - sort_indices.reinitialize(edges.size()); - std::iota(sort_indices.begin(), sort_indices.end(), 0); - std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { - return sort_weights[a] < sort_weights[b]; - }); - const int index_in_sort_wrapped = mod_i(index_in_sort, edges.size()); - edge_of_vertex[selection_i] = edge_indices[sort_indices[index_in_sort_wrapped]]; + if (use_sorting) { + /* Retrieve the connected edge indices as 64 bit integers for #materialize_compressed. */ + edge_indices.reinitialize(edges.size()); + convert_span(edges, edge_indices); + + /* Retrieve a compressed array of weights for each edge. */ + sort_weights.reinitialize(edges.size()); + all_sort_weights.materialize_compressed(IndexMask(edge_indices), + sort_weights.as_mutable_span()); + + /* Sort a separate array of compressed indices corresponding to the compressed weights. + * This allows using `materialize_compressed` to avoid virtual function call overhead + * when accessing values in the sort weights. However, it means a separate array of + * indices within the compressed array is necessary for sorting. */ + sort_indices.reinitialize(edges.size()); + std::iota(sort_indices.begin(), sort_indices.end(), 0); + std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { + return sort_weights[a] < sort_weights[b]; + }); + + edge_of_vertex[selection_i] = edge_indices[sort_indices[index_in_sort_wrapped]]; + } + else { + edge_of_vertex[selection_i] = edge_indices[index_in_sort_wrapped]; + } } });