Fix T95666: Crash when attempting multires linear subdivide
The crash was happening when the mesh had loose edges. Loose edges are not part of OpenSubdiv topology and hence should not be communicated to the refiner. Pass ta boolean flag indicating whether an edge is loose or not in the mesh foreach routines, which seems to be the easiest way.
This commit is contained in:
parent
04d55038ee
commit
94f0230230
Notes:
blender-bot
2023-02-14 00:06:52 +01:00
Referenced by issue #95666, Crash when attempting multires linear subdivide
|
@ -74,6 +74,7 @@ typedef void (*SubdivForeachEdgeCb)(const struct SubdivForeachContext *context,
|
|||
void *tls,
|
||||
int coarse_edge_index,
|
||||
int subdiv_edge_index,
|
||||
bool is_loose,
|
||||
int subdiv_v1,
|
||||
int subdiv_v2);
|
||||
|
||||
|
|
|
@ -825,6 +825,7 @@ static void foreach_edge(const struct SubdivForeachContext *foreach_context,
|
|||
void *UNUSED(tls),
|
||||
const int coarse_edge_index,
|
||||
const int UNUSED(subdiv_edge_index),
|
||||
const bool is_loose,
|
||||
const int subdiv_v1,
|
||||
const int subdiv_v2)
|
||||
{
|
||||
|
@ -832,7 +833,9 @@ static void foreach_edge(const struct SubdivForeachContext *foreach_context,
|
|||
const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context;
|
||||
|
||||
if (reshape_smooth_context->smoothing_type == MULTIRES_SUBDIVIDE_LINEAR) {
|
||||
store_edge(reshape_smooth_context, subdiv_v1, subdiv_v2, (char)255);
|
||||
if (!is_loose) {
|
||||
store_edge(reshape_smooth_context, subdiv_v1, subdiv_v2, (char)255);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -734,7 +734,7 @@ static int subdiv_foreach_edges_row(SubdivForeachTaskContext *ctx,
|
|||
const int v1 = vertex_index;
|
||||
const int v2 = vertex_index + 1;
|
||||
ctx->foreach_context->edge(
|
||||
ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, v1, v2);
|
||||
ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, false, v1, v2);
|
||||
vertex_index += 1;
|
||||
}
|
||||
return subdiv_edge_index;
|
||||
|
@ -762,7 +762,7 @@ static int subdiv_foreach_edges_column(SubdivForeachTaskContext *ctx,
|
|||
const int v1 = vertex_index;
|
||||
const int v2 = vertex_index + num_edges_per_row;
|
||||
ctx->foreach_context->edge(
|
||||
ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, v1, v2);
|
||||
ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, false, v1, v2);
|
||||
vertex_index += 1;
|
||||
}
|
||||
return subdiv_edge_index;
|
||||
|
@ -862,7 +862,7 @@ static void subdiv_foreach_edges_all_patches_regular(SubdivForeachTaskContext *c
|
|||
const int v1 = (flip) ? (start_edge_vertex + (resolution - i - 3)) : (start_edge_vertex + i);
|
||||
const int v2 = side_start_index + side_stride * i;
|
||||
ctx->foreach_context->edge(
|
||||
ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, v1, v2);
|
||||
ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -926,7 +926,7 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c
|
|||
const int v1 = current_patch_vertex_index;
|
||||
const int v2 = next_path_vertex_index;
|
||||
ctx->foreach_context->edge(
|
||||
ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, v1, v2);
|
||||
ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2);
|
||||
current_patch_vertex_index += ptex_face_inner_resolution + 1;
|
||||
next_path_vertex_index += 1;
|
||||
}
|
||||
|
@ -940,7 +940,7 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c
|
|||
const int v1 = center_vertex_index;
|
||||
const int v2 = current_patch_end_vertex_index;
|
||||
ctx->foreach_context->edge(
|
||||
ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, v1, v2);
|
||||
ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2);
|
||||
}
|
||||
}
|
||||
/* Connect inner path of patch to boundary. */
|
||||
|
@ -964,7 +964,7 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c
|
|||
(start_edge_vertex + i);
|
||||
const int v2 = side_start_index + i;
|
||||
ctx->foreach_context->edge(
|
||||
ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, v1, v2);
|
||||
ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2);
|
||||
}
|
||||
}
|
||||
if (ptex_face_resolution >= 3) {
|
||||
|
@ -978,7 +978,7 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c
|
|||
(start_edge_vertex + i);
|
||||
const int v2 = side_start_index + (ptex_face_inner_resolution + 1) * i;
|
||||
ctx->foreach_context->edge(
|
||||
ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, v1, v2);
|
||||
ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2);
|
||||
}
|
||||
}
|
||||
prev_coarse_loop = coarse_loop;
|
||||
|
@ -1015,6 +1015,8 @@ static void subdiv_foreach_boundary_edges(SubdivForeachTaskContext *ctx,
|
|||
const int resolution = ctx->settings->resolution;
|
||||
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
|
||||
const int num_subdiv_edges_per_coarse_edge = resolution - 1;
|
||||
const bool is_loose = !BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, coarse_edge_index);
|
||||
|
||||
int subdiv_edge_index = ctx->edge_boundary_offset +
|
||||
coarse_edge_index * num_subdiv_edges_per_coarse_edge;
|
||||
int last_vertex_index = ctx->vertices_corner_offset + coarse_edge->v1;
|
||||
|
@ -1023,13 +1025,13 @@ static void subdiv_foreach_boundary_edges(SubdivForeachTaskContext *ctx,
|
|||
const int v2 = ctx->vertices_edge_offset +
|
||||
coarse_edge_index * num_subdiv_vertices_per_coarse_edge + i;
|
||||
ctx->foreach_context->edge(
|
||||
ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, v1, v2);
|
||||
ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, is_loose, v1, v2);
|
||||
last_vertex_index = v2;
|
||||
}
|
||||
const int v1 = last_vertex_index;
|
||||
const int v2 = ctx->vertices_corner_offset + coarse_edge->v2;
|
||||
ctx->foreach_context->edge(
|
||||
ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, v1, v2);
|
||||
ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, is_loose, v1, v2);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -767,6 +767,7 @@ static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context,
|
|||
void *UNUSED(tls),
|
||||
const int coarse_edge_index,
|
||||
const int subdiv_edge_index,
|
||||
const bool UNUSED(is_loose),
|
||||
const int subdiv_v1,
|
||||
const int subdiv_v2)
|
||||
{
|
||||
|
|
|
@ -820,6 +820,7 @@ static void draw_subdiv_edge_cb(const SubdivForeachContext *foreach_context,
|
|||
void *UNUSED(tls),
|
||||
const int coarse_edge_index,
|
||||
const int subdiv_edge_index,
|
||||
const bool UNUSED(is_loose),
|
||||
const int UNUSED(subdiv_v1),
|
||||
const int UNUSED(subdiv_v2))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue