From 8a7085b9d45b5e364978672ac50cff4e7ee9e269 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 26 Sep 2019 12:01:52 +0200 Subject: Fix T70163: Error painting with Subdivision at end of stack Deformation of subdivision surface modifier was using wrong coordinates for the coarse mesh: as the modifier flow goes the coordinates are to be taken from the input array of coordinates. --- source/blender/blenkernel/intern/multires_reshape.c | 2 +- source/blender/blenkernel/intern/subdiv_ccg.c | 2 +- source/blender/blenkernel/intern/subdiv_deform.c | 2 +- source/blender/blenkernel/intern/subdiv_eval.c | 21 ++++++++++++++++----- source/blender/blenkernel/intern/subdiv_mesh.c | 2 +- 5 files changed, 20 insertions(+), 9 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c index 3257bc1b193..4e4a8831518 100644 --- a/source/blender/blenkernel/intern/multires_reshape.c +++ b/source/blender/blenkernel/intern/multires_reshape.c @@ -795,7 +795,7 @@ static Subdiv *multires_create_subdiv_for_reshape(struct Depsgraph *depsgraph, SubdivSettings subdiv_settings; BKE_multires_subdiv_settings_init(&subdiv_settings, mmd); Subdiv *subdiv = BKE_subdiv_new_from_mesh(&subdiv_settings, deformed_mesh); - if (!BKE_subdiv_eval_update_from_mesh(subdiv, deformed_mesh)) { + if (!BKE_subdiv_eval_update_from_mesh(subdiv, deformed_mesh, NULL)) { BKE_subdiv_free(subdiv); return NULL; } diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c index 843e68108c3..471cca53900 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg.c +++ b/source/blender/blenkernel/intern/subdiv_ccg.c @@ -591,7 +591,7 @@ Mesh *BKE_subdiv_to_ccg_mesh(Subdiv *subdiv, { /* Make sure evaluator is ready. */ BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_CCG); - if (!BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh)) { + if (!BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh, NULL)) { if (coarse_mesh->totpoly) { return false; } diff --git a/source/blender/blenkernel/intern/subdiv_deform.c b/source/blender/blenkernel/intern/subdiv_deform.c index 5b9335a503e..9c7949e7bdb 100644 --- a/source/blender/blenkernel/intern/subdiv_deform.c +++ b/source/blender/blenkernel/intern/subdiv_deform.c @@ -195,7 +195,7 @@ void BKE_subdiv_deform_coarse_vertices(struct Subdiv *subdiv, /* Make sure evaluator is up to date with possible new topology, and that * is is refined for the new positions of coarse vertices. */ - if (!BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh)) { + if (!BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh, vertex_cos)) { /* This could happen in two situations: * - OpenSubdiv is disabled. * - Something totally bad happened, and OpenSubdiv rejected our diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c index 419371c7a4b..bf5e886dd22 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -61,7 +61,9 @@ bool BKE_subdiv_eval_begin(Subdiv *subdiv) return true; } -static void set_coarse_positions(Subdiv *subdiv, const Mesh *mesh) +static void set_coarse_positions(Subdiv *subdiv, + const Mesh *mesh, + const float (*coarse_vertex_cos)[3]) { const MVert *mvert = mesh->mvert; const MLoop *mloop = mesh->mloop; @@ -83,8 +85,15 @@ static void set_coarse_positions(Subdiv *subdiv, const Mesh *mesh) if (!BLI_BITMAP_TEST_BOOL(vertex_used_map, vertex_index)) { continue; } - const MVert *vertex = &mvert[vertex_index]; - subdiv->evaluator->setCoarsePositions(subdiv->evaluator, vertex->co, manifold_veretx_index, 1); + const float *vertex_co; + if (coarse_vertex_cos != NULL) { + vertex_co = coarse_vertex_cos[vertex_index]; + } + else { + const MVert *vertex = &mvert[vertex_index]; + vertex_co = vertex->co; + } + subdiv->evaluator->setCoarsePositions(subdiv->evaluator, vertex_co, manifold_veretx_index, 1); manifold_veretx_index++; } MEM_freeN(vertex_used_map); @@ -112,7 +121,9 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv, } } -bool BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh) +bool BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, + const Mesh *mesh, + const float (*coarse_vertex_cos)[3]) { if (!BKE_subdiv_eval_begin(subdiv)) { return false; @@ -123,7 +134,7 @@ bool BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh) return false; } /* Set coordinates of base mesh vertices. */ - set_coarse_positions(subdiv, mesh); + set_coarse_positions(subdiv, mesh, coarse_vertex_cos); /* Set face-varyign data to UV maps. */ const int num_uv_layers = CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV); for (int layer_index = 0; layer_index < num_uv_layers; layer_index++) { diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 57330575735..a30dde6284b 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -1166,7 +1166,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv, /* Make sure evaluator is up to date with possible new topology, and that * is is refined for the new positions of coarse vertices. */ - if (!BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh)) { + if (!BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh, NULL)) { /* This could happen in two situations: * - OpenSubdiv is disabled. * - Something totally bad happened, and OpenSubdiv rejected our -- cgit v1.2.3