Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_weld.cc
| Show First 20 Lines • Show All 368 Lines • ▼ Show 20 Lines | |||||
| #endif /* USE_WELD_DEBUG */ | #endif /* USE_WELD_DEBUG */ | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Weld Vert API | /** \name Weld Vert API | ||||
| * \{ */ | * \{ */ | ||||
| static Vector<WeldVert> weld_vert_ctx_alloc_and_setup(const int mvert_len, | static Vector<WeldVert> weld_vert_ctx_alloc_and_setup(const int mvert_len, Span<int> vert_dest_map) | ||||
| Span<int> vert_dest_map) | |||||
| { | { | ||||
| Vector<WeldVert> wvert; | Vector<WeldVert> wvert(mvert_len); | ||||
HooglyBoogly: Wouldn't it be possible to calculate the size of this exactly, depending on the `vert_kill_len`… | |||||
mano-wiiAuthorUnsubmitted Done Inline ActionsUnfortunately not. mano-wii: Unfortunately not.
`vert_kill_len` only indicates how many vertices are going to be killed, but… | |||||
| wvert.reserve(mvert_len); | |||||
| int wvert_len = 0; | |||||
| const int *v_dest_iter = &vert_dest_map[0]; | const int *v_dest_iter = &vert_dest_map[0]; | ||||
| for (int i = 0; i < mvert_len; i++, v_dest_iter++) { | for (int i = 0; i < mvert_len; i++, v_dest_iter++) { | ||||
| if (*v_dest_iter != OUT_OF_CONTEXT) { | if (*v_dest_iter != OUT_OF_CONTEXT) { | ||||
| wvert.append({*v_dest_iter, i}); | WeldVert wv{*v_dest_iter, i}; | ||||
| wvert[wvert_len++] = wv; | |||||
| } | } | ||||
| } | } | ||||
| wvert.resize(wvert_len); | |||||
| return wvert; | return wvert; | ||||
| } | } | ||||
| static void weld_vert_groups_setup(const int mvert_len, | static void weld_vert_groups_setup(const int mvert_len, | ||||
| Span<WeldVert> wvert, | Span<WeldVert> wvert, | ||||
| Span<int> vert_dest_map, | Span<int> vert_dest_map, | ||||
| MutableSpan<int> r_vert_groups_map, | MutableSpan<int> r_vert_groups_map, | ||||
| Array<int> &r_vert_groups_buffer, | Array<int> &r_vert_groups_buffer, | ||||
| ▲ Show 20 Lines • Show All 181 Lines • ▼ Show 20 Lines | static Vector<WeldEdge> weld_edge_ctx_alloc(const MEdge *medge, | ||||
| const int medge_len, | const int medge_len, | ||||
| Span<int> vert_dest_map, | Span<int> vert_dest_map, | ||||
| MutableSpan<int> r_edge_dest_map, | MutableSpan<int> r_edge_dest_map, | ||||
| MutableSpan<int> r_edge_ctx_map) | MutableSpan<int> r_edge_ctx_map) | ||||
| { | { | ||||
| /* Edge Context. */ | /* Edge Context. */ | ||||
| int wedge_len = 0; | int wedge_len = 0; | ||||
| Vector<WeldEdge> wedge; | Vector<WeldEdge> wedge(medge_len); | ||||
| wedge.reserve(medge_len); | |||||
| const MEdge *me = &medge[0]; | const MEdge *me = &medge[0]; | ||||
| int *e_dest_iter = &r_edge_dest_map[0]; | int *e_dest_iter = &r_edge_dest_map[0]; | ||||
| int *iter = &r_edge_ctx_map[0]; | int *iter = &r_edge_ctx_map[0]; | ||||
| for (int i = 0; i < medge_len; i++, me++, iter++, e_dest_iter++) { | for (int i = 0; i < medge_len; i++, me++, iter++, e_dest_iter++) { | ||||
| int v1 = me->v1; | int v1 = me->v1; | ||||
| int v2 = me->v2; | int v2 = me->v2; | ||||
| int v_dest_1 = vert_dest_map[v1]; | int v_dest_1 = vert_dest_map[v1]; | ||||
| int v_dest_2 = vert_dest_map[v2]; | int v_dest_2 = vert_dest_map[v2]; | ||||
| if ((v_dest_1 != OUT_OF_CONTEXT) || (v_dest_2 != OUT_OF_CONTEXT)) { | if ((v_dest_1 != OUT_OF_CONTEXT) || (v_dest_2 != OUT_OF_CONTEXT)) { | ||||
| WeldEdge we{}; | WeldEdge we{}; | ||||
| we.vert_a = (v_dest_1 != OUT_OF_CONTEXT) ? v_dest_1 : v1; | we.vert_a = (v_dest_1 != OUT_OF_CONTEXT) ? v_dest_1 : v1; | ||||
| we.vert_b = (v_dest_2 != OUT_OF_CONTEXT) ? v_dest_2 : v2; | we.vert_b = (v_dest_2 != OUT_OF_CONTEXT) ? v_dest_2 : v2; | ||||
| we.edge_dest = OUT_OF_CONTEXT; | we.edge_dest = OUT_OF_CONTEXT; | ||||
| we.edge_orig = i; | we.edge_orig = i; | ||||
| wedge.append(we); | wedge[wedge_len] = we; | ||||
| *e_dest_iter = i; | *e_dest_iter = i; | ||||
| *iter = wedge_len++; | *iter = wedge_len++; | ||||
| } | } | ||||
| else { | else { | ||||
| *e_dest_iter = OUT_OF_CONTEXT; | *e_dest_iter = OUT_OF_CONTEXT; | ||||
| *iter = OUT_OF_CONTEXT; | *iter = OUT_OF_CONTEXT; | ||||
| } | } | ||||
| } | } | ||||
| wedge.resize(wedge_len); | |||||
| return wedge; | return wedge; | ||||
| } | } | ||||
| static void weld_edge_groups_setup(const int medge_len, | static void weld_edge_groups_setup(const int medge_len, | ||||
| const int edge_kill_len, | const int edge_kill_len, | ||||
| MutableSpan<WeldEdge> wedge, | MutableSpan<WeldEdge> wedge, | ||||
| Span<int> wedge_map, | Span<int> wedge_map, | ||||
| MutableSpan<int> r_edge_groups_map, | MutableSpan<int> r_edge_groups_map, | ||||
| ▲ Show 20 Lines • Show All 190 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| /* Loop/Poly Context. */ | /* Loop/Poly Context. */ | ||||
| Array<int> loop_map(mloop.size()); | Array<int> loop_map(mloop.size()); | ||||
| Array<int> poly_map(mpoly.size()); | Array<int> poly_map(mpoly.size()); | ||||
| int wloop_len = 0; | int wloop_len = 0; | ||||
| int wpoly_len = 0; | int wpoly_len = 0; | ||||
| int max_ctx_poly_len = 4; | int max_ctx_poly_len = 4; | ||||
| Vector<WeldLoop> wloop; | Vector<WeldLoop> wloop(mloop.size()); | ||||
| wloop.reserve(mloop.size()); | |||||
| Vector<WeldPoly> wpoly; | Vector<WeldPoly> wpoly(mpoly.size()); | ||||
| wpoly.reserve(mpoly.size()); | |||||
| int maybe_new_poly = 0; | int maybe_new_poly = 0; | ||||
| const MPoly *mp = &mpoly[0]; | const MPoly *mp = &mpoly[0]; | ||||
| int *iter = &poly_map[0]; | int *iter = &poly_map[0]; | ||||
| int *loop_map_iter = &loop_map[0]; | int *loop_map_iter = &loop_map[0]; | ||||
| for (int i = 0; i < mpoly.size(); i++, mp++, iter++) { | for (int i = 0; i < mpoly.size(); i++, mp++, iter++) { | ||||
| const int loopstart = mp->loopstart; | const int loopstart = mp->loopstart; | ||||
| Show All 15 Lines | for (int j = totloop; j--; l++, ml++, loop_map_iter++) { | ||||
| vert_ctx_len++; | vert_ctx_len++; | ||||
| } | } | ||||
| if (is_vert_ctx || is_edge_ctx) { | if (is_vert_ctx || is_edge_ctx) { | ||||
| WeldLoop wl{}; | WeldLoop wl{}; | ||||
| wl.vert = is_vert_ctx ? v_dest : v; | wl.vert = is_vert_ctx ? v_dest : v; | ||||
| wl.edge = is_edge_ctx ? e_dest : e; | wl.edge = is_edge_ctx ? e_dest : e; | ||||
| wl.loop_orig = l; | wl.loop_orig = l; | ||||
| wl.loop_skip_to = OUT_OF_CONTEXT; | wl.loop_skip_to = OUT_OF_CONTEXT; | ||||
| wloop.append(wl); | wloop[wloop_len] = wl; | ||||
| *loop_map_iter = wloop_len++; | *loop_map_iter = wloop_len++; | ||||
| } | } | ||||
| else { | else { | ||||
| *loop_map_iter = OUT_OF_CONTEXT; | *loop_map_iter = OUT_OF_CONTEXT; | ||||
| } | } | ||||
| } | } | ||||
| if (wloop_len != prev_wloop_len) { | if (wloop_len != prev_wloop_len) { | ||||
| int loops_len = wloop_len - prev_wloop_len; | int loops_len = wloop_len - prev_wloop_len; | ||||
| WeldPoly wp{}; | WeldPoly wp{}; | ||||
| wp.poly_dst = OUT_OF_CONTEXT; | wp.poly_dst = OUT_OF_CONTEXT; | ||||
| wp.poly_orig = i; | wp.poly_orig = i; | ||||
| wp.loops.len = loops_len; | wp.loops.len = loops_len; | ||||
| wp.loops.ofs = prev_wloop_len; | wp.loops.ofs = prev_wloop_len; | ||||
| wp.loop_start = loopstart; | wp.loop_start = loopstart; | ||||
| wp.loop_end = loopstart + totloop - 1; | wp.loop_end = loopstart + totloop - 1; | ||||
| wp.len = totloop; | wp.len = totloop; | ||||
| wpoly.append(wp); | wpoly[wpoly_len] = wp; | ||||
| *iter = wpoly_len++; | *iter = wpoly_len++; | ||||
| if (totloop > 5 && vert_ctx_len > 1) { | if (totloop > 5 && vert_ctx_len > 1) { | ||||
| int max_new = (totloop / 3) - 1; | int max_new = (totloop / 3) - 1; | ||||
| vert_ctx_len /= 2; | vert_ctx_len /= 2; | ||||
| maybe_new_poly += MIN2(max_new, vert_ctx_len); | maybe_new_poly += MIN2(max_new, vert_ctx_len); | ||||
| CLAMP_MIN(max_ctx_poly_len, totloop); | CLAMP_MIN(max_ctx_poly_len, totloop); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| *iter = OUT_OF_CONTEXT; | *iter = OUT_OF_CONTEXT; | ||||
| } | } | ||||
| } | } | ||||
| if (mpoly.size() < (wpoly_len + maybe_new_poly)) { | if (mpoly.size() < (wpoly_len + maybe_new_poly)) { | ||||
| wpoly.resize(wpoly_len + maybe_new_poly); | wpoly.resize(wpoly_len + maybe_new_poly); | ||||
| } | } | ||||
| wloop.resize(wloop_len); | |||||
| WeldPoly *poly_new = wpoly.data() + wpoly_len; | WeldPoly *poly_new = wpoly.data() + wpoly_len; | ||||
| r_weld_mesh->wloop = std::move(wloop); | r_weld_mesh->wloop = std::move(wloop); | ||||
| r_weld_mesh->wpoly = std::move(wpoly); | r_weld_mesh->wpoly = std::move(wpoly); | ||||
| r_weld_mesh->wpoly_new = poly_new; | r_weld_mesh->wpoly_new = poly_new; | ||||
| r_weld_mesh->wloop_len = wloop_len; | r_weld_mesh->wloop_len = wloop_len; | ||||
| r_weld_mesh->wpoly_len = wpoly_len; | r_weld_mesh->wpoly_len = wpoly_len; | ||||
| ▲ Show 20 Lines • Show All 1,112 Lines • Show Last 20 Lines | |||||
Wouldn't it be possible to calculate the size of this exactly, depending on the vert_kill_len and the original number of vertices?
Then it wouldn't even need to be a vector.