Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
| Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| /* Move scaling center back to where it was. */ | /* Move scaling center back to where it was. */ | ||||
| add_v3_v3(transform.values[3], center); | add_v3_v3(transform.values[3], center); | ||||
| return transform; | return transform; | ||||
| } | } | ||||
| using GetVertexIndicesFn = FunctionRef<void(Span<MEdge> edges, | using GetVertexIndicesFn = FunctionRef<void(Span<MEdge> edges, | ||||
| Span<MPoly> polys, | Span<MPoly> polys, | ||||
| Span<MLoop> loops, | Span<int> corner_verts, | ||||
| int element_index, | int element_index, | ||||
| VectorSet<int> &r_vertex_indices)>; | VectorSet<int> &r_vertex_indices)>; | ||||
| static void scale_vertex_islands_uniformly(Mesh &mesh, | static void scale_vertex_islands_uniformly(Mesh &mesh, | ||||
| const Span<ElementIsland> islands, | const Span<ElementIsland> islands, | ||||
| const UniformScaleParams ¶ms, | const UniformScaleParams ¶ms, | ||||
| const GetVertexIndicesFn get_vertex_indices) | const GetVertexIndicesFn get_vertex_indices) | ||||
| { | { | ||||
| MutableSpan<float3> positions = mesh.vert_positions_for_write(); | MutableSpan<float3> positions = mesh.vert_positions_for_write(); | ||||
| const Span<MEdge> edges = mesh.edges(); | const Span<MEdge> edges = mesh.edges(); | ||||
| const Span<MPoly> polys = mesh.polys(); | const Span<MPoly> polys = mesh.polys(); | ||||
| const Span<MLoop> loops = mesh.loops(); | const Span<int> corner_verts = mesh.corner_verts(); | ||||
| threading::parallel_for(islands.index_range(), 256, [&](const IndexRange range) { | threading::parallel_for(islands.index_range(), 256, [&](const IndexRange range) { | ||||
| for (const int island_index : range) { | for (const int island_index : range) { | ||||
| const ElementIsland &island = islands[island_index]; | const ElementIsland &island = islands[island_index]; | ||||
| float scale = 0.0f; | float scale = 0.0f; | ||||
| float3 center = {0.0f, 0.0f, 0.0f}; | float3 center = {0.0f, 0.0f, 0.0f}; | ||||
| VectorSet<int> vertex_indices; | VectorSet<int> vertex_indices; | ||||
| for (const int poly_index : island.element_indices) { | for (const int poly_index : island.element_indices) { | ||||
| get_vertex_indices(edges, polys, loops, poly_index, vertex_indices); | get_vertex_indices(edges, polys, corner_verts, poly_index, vertex_indices); | ||||
| center += params.centers[poly_index]; | center += params.centers[poly_index]; | ||||
| scale += params.scales[poly_index]; | scale += params.scales[poly_index]; | ||||
| } | } | ||||
| /* Divide by number of elements to get the average. */ | /* Divide by number of elements to get the average. */ | ||||
| const float f = 1.0f / island.element_indices.size(); | const float f = 1.0f / island.element_indices.size(); | ||||
| scale *= f; | scale *= f; | ||||
| center *= f; | center *= f; | ||||
| Show All 10 Lines | |||||
| static void scale_vertex_islands_on_axis(Mesh &mesh, | static void scale_vertex_islands_on_axis(Mesh &mesh, | ||||
| const Span<ElementIsland> islands, | const Span<ElementIsland> islands, | ||||
| const AxisScaleParams ¶ms, | const AxisScaleParams ¶ms, | ||||
| const GetVertexIndicesFn get_vertex_indices) | const GetVertexIndicesFn get_vertex_indices) | ||||
| { | { | ||||
| MutableSpan<float3> positions = mesh.vert_positions_for_write(); | MutableSpan<float3> positions = mesh.vert_positions_for_write(); | ||||
| const Span<MEdge> edges = mesh.edges(); | const Span<MEdge> edges = mesh.edges(); | ||||
| const Span<MPoly> polys = mesh.polys(); | const Span<MPoly> polys = mesh.polys(); | ||||
| const Span<MLoop> loops = mesh.loops(); | const Span<int> corner_verts = mesh.corner_verts(); | ||||
| threading::parallel_for(islands.index_range(), 256, [&](const IndexRange range) { | threading::parallel_for(islands.index_range(), 256, [&](const IndexRange range) { | ||||
| for (const int island_index : range) { | for (const int island_index : range) { | ||||
| const ElementIsland &island = islands[island_index]; | const ElementIsland &island = islands[island_index]; | ||||
| float scale = 0.0f; | float scale = 0.0f; | ||||
| float3 center = {0.0f, 0.0f, 0.0f}; | float3 center = {0.0f, 0.0f, 0.0f}; | ||||
| float3 axis = {0.0f, 0.0f, 0.0f}; | float3 axis = {0.0f, 0.0f, 0.0f}; | ||||
| VectorSet<int> vertex_indices; | VectorSet<int> vertex_indices; | ||||
| for (const int poly_index : island.element_indices) { | for (const int poly_index : island.element_indices) { | ||||
| get_vertex_indices(edges, polys, loops, poly_index, vertex_indices); | get_vertex_indices(edges, polys, corner_verts, poly_index, vertex_indices); | ||||
| center += params.centers[poly_index]; | center += params.centers[poly_index]; | ||||
| scale += params.scales[poly_index]; | scale += params.scales[poly_index]; | ||||
| axis += params.axis_vectors[poly_index]; | axis += params.axis_vectors[poly_index]; | ||||
| } | } | ||||
| /* Divide by number of elements to get the average. */ | /* Divide by number of elements to get the average. */ | ||||
| const float f = 1.0f / island.element_indices.size(); | const float f = 1.0f / island.element_indices.size(); | ||||
| scale *= f; | scale *= f; | ||||
| Show All 12 Lines | |||||
| }); | }); | ||||
| BKE_mesh_tag_coords_changed(&mesh); | BKE_mesh_tag_coords_changed(&mesh); | ||||
| } | } | ||||
| static Vector<ElementIsland> prepare_face_islands(const Mesh &mesh, const IndexMask face_selection) | static Vector<ElementIsland> prepare_face_islands(const Mesh &mesh, const IndexMask face_selection) | ||||
| { | { | ||||
| const Span<MPoly> polys = mesh.polys(); | const Span<MPoly> polys = mesh.polys(); | ||||
| const Span<MLoop> loops = mesh.loops(); | const Span<int> corner_verts = mesh.corner_verts(); | ||||
| /* Use the disjoint set data structure to determine which vertices have to be scaled together. */ | /* Use the disjoint set data structure to determine which vertices have to be scaled together. */ | ||||
| DisjointSet<int> disjoint_set(mesh.totvert); | DisjointSet<int> disjoint_set(mesh.totvert); | ||||
| for (const int poly_index : face_selection) { | for (const int poly_index : face_selection) { | ||||
| const MPoly &poly = polys[poly_index]; | const MPoly &poly = polys[poly_index]; | ||||
| const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); | const Span<int> poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); | ||||
| for (const int loop_index : IndexRange(poly.totloop - 1)) { | for (const int loop_index : IndexRange(poly.totloop - 1)) { | ||||
| const int v1 = poly_loops[loop_index].v; | const int v1 = poly_verts[loop_index]; | ||||
| const int v2 = poly_loops[loop_index + 1].v; | const int v2 = poly_verts[loop_index + 1]; | ||||
| disjoint_set.join(v1, v2); | disjoint_set.join(v1, v2); | ||||
| } | } | ||||
| disjoint_set.join(poly_loops.first().v, poly_loops.last().v); | disjoint_set.join(poly_verts.first(), poly_verts.last()); | ||||
| } | } | ||||
| VectorSet<int> island_ids; | VectorSet<int> island_ids; | ||||
| Vector<ElementIsland> islands; | Vector<ElementIsland> islands; | ||||
| /* There are at most as many islands as there are selected faces. */ | /* There are at most as many islands as there are selected faces. */ | ||||
| islands.reserve(face_selection.size()); | islands.reserve(face_selection.size()); | ||||
| /* Gather all of the face indices in each island into separate vectors. */ | /* Gather all of the face indices in each island into separate vectors. */ | ||||
| for (const int poly_index : face_selection) { | for (const int poly_index : face_selection) { | ||||
| const MPoly &poly = polys[poly_index]; | const MPoly &poly = polys[poly_index]; | ||||
| const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); | const Span<int> poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); | ||||
| const int island_id = disjoint_set.find_root(poly_loops[0].v); | const int island_id = disjoint_set.find_root(poly_verts[0]); | ||||
| const int island_index = island_ids.index_of_or_add(island_id); | const int island_index = island_ids.index_of_or_add(island_id); | ||||
| if (island_index == islands.size()) { | if (island_index == islands.size()) { | ||||
| islands.append_as(); | islands.append_as(); | ||||
| } | } | ||||
| ElementIsland &island = islands[island_index]; | ElementIsland &island = islands[island_index]; | ||||
| island.element_indices.append(poly_index); | island.element_indices.append(poly_index); | ||||
| } | } | ||||
| return islands; | return islands; | ||||
| } | } | ||||
| static void get_face_verts(const Span<MEdge> /*edges*/, | static void get_face_verts(const Span<MEdge> /*edges*/, | ||||
| const Span<MPoly> polys, | const Span<MPoly> polys, | ||||
| const Span<MLoop> loops, | const Span<int> corner_verts, | ||||
| int face_index, | int face_index, | ||||
| VectorSet<int> &r_vertex_indices) | VectorSet<int> &r_vertex_indices) | ||||
| { | { | ||||
| const MPoly &poly = polys[face_index]; | const MPoly &poly = polys[face_index]; | ||||
| const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); | r_vertex_indices.add_multiple(corner_verts.slice(poly.loopstart, poly.totloop)); | ||||
| for (const MLoop &loop : poly_loops) { | |||||
| r_vertex_indices.add(loop.v); | |||||
| } | |||||
| } | } | ||||
| static AxisScaleParams evaluate_axis_scale_fields(FieldEvaluator &evaluator, | static AxisScaleParams evaluate_axis_scale_fields(FieldEvaluator &evaluator, | ||||
| const AxisScaleFields &fields) | const AxisScaleFields &fields) | ||||
| { | { | ||||
| AxisScaleParams out; | AxisScaleParams out; | ||||
| evaluator.set_selection(fields.selection); | evaluator.set_selection(fields.selection); | ||||
| evaluator.add(fields.scale, &out.scales); | evaluator.add(fields.scale, &out.scales); | ||||
| ▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
| island.element_indices.append(edge_index); | island.element_indices.append(edge_index); | ||||
| } | } | ||||
| return islands; | return islands; | ||||
| } | } | ||||
| static void get_edge_verts(const Span<MEdge> edges, | static void get_edge_verts(const Span<MEdge> edges, | ||||
| const Span<MPoly> /*polys*/, | const Span<MPoly> /*polys*/, | ||||
| const Span<MLoop> /*loops*/, | const Span<int> /*corner_verts*/, | ||||
| int edge_index, | int edge_index, | ||||
| VectorSet<int> &r_vertex_indices) | VectorSet<int> &r_vertex_indices) | ||||
| { | { | ||||
| const MEdge &edge = edges[edge_index]; | const MEdge &edge = edges[edge_index]; | ||||
| r_vertex_indices.add(edge.v1); | r_vertex_indices.add(edge.v1); | ||||
| r_vertex_indices.add(edge.v2); | r_vertex_indices.add(edge.v2); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 91 Lines • Show Last 20 Lines | |||||