Fix #35149: solidify modifier + vertex parent not working after going in and out

of editmode on the child object.

Problem was that the object custom data mask was not taken into account when
rebuilding the derivedmesh in some cases, which is needed for the derivedmesh
to contain the mapping back to the original vertices. Now this data mask is
used for any derivedmesh build that will be cached.

Also problematic was that the datamask for the active object was applied to
all objects in the scene, which caused the parent object to be recalculated
when it didn't need to be. Now this datamask is only used for the active object.
This commit is contained in:
Brecht Van Lommel
2013-05-01 14:34:12 +00:00
parent 04cbb3ad14
commit c8cf9415de
6 changed files with 40 additions and 34 deletions

View File

@@ -2258,9 +2258,38 @@ static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, C
em->derivedCage->needsFree = 0;
}
static CustomDataMask object_get_datamask(Scene *scene, Object *ob)
{
Object *actob = scene->basact ? scene->basact->object : NULL;
CustomDataMask mask = ob->customdata_mask;
if (ob == actob) {
/* check if we need tfaces & mcols due to face select or texture paint */
if (paint_facesel_test(ob) || (ob->mode & OB_MODE_TEXTURE_PAINT)) {
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
}
/* check if we need mcols due to vertex paint or weightpaint */
if (ob->mode & OB_MODE_VERTEX_PAINT) {
mask |= CD_MASK_MCOL;
}
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
mask |= CD_MASK_PREVIEW_MCOL;
}
if (ob->mode & OB_MODE_EDIT)
mask |= CD_MASK_MVERT_SKIN;
}
return mask;
}
void makeDerivedMesh(Scene *scene, Object *ob, BMEditMesh *em,
CustomDataMask dataMask, int build_shapekey_layers)
{
dataMask |= object_get_datamask(scene, ob);
if (em) {
editbmesh_build_data(scene, ob, em, dataMask);
}
@@ -2276,6 +2305,8 @@ DerivedMesh *mesh_get_derived_final(Scene *scene, Object *ob, CustomDataMask dat
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
*/
dataMask |= object_get_datamask(scene, ob);
if (!ob->derivedFinal || (dataMask & ob->lastDataMask) != dataMask)
mesh_build_data(scene, ob, dataMask, 0);
@@ -2287,6 +2318,8 @@ DerivedMesh *mesh_get_derived_deform(Scene *scene, Object *ob, CustomDataMask da
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
*/
dataMask |= object_get_datamask(scene, ob);
if (!ob->derivedDeform || (dataMask & ob->lastDataMask) != dataMask)
mesh_build_data(scene, ob, dataMask, 0);
@@ -2377,6 +2410,8 @@ DerivedMesh *editbmesh_get_derived_cage_and_final(Scene *scene, Object *obedit,
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
*/
dataMask |= object_get_datamask(scene, obedit);
if (!em->derivedCage ||
(em->lastDataMask & dataMask) != dataMask)
{
@@ -2392,6 +2427,8 @@ DerivedMesh *editbmesh_get_derived_cage(Scene *scene, Object *obedit, BMEditMesh
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
*/
dataMask |= object_get_datamask(scene, obedit);
if (!em->derivedCage ||
(em->lastDataMask & dataMask) != dataMask)
{

View File

@@ -2727,7 +2727,7 @@ void BKE_object_handle_update_ex(Scene *scene, Object *ob,
#else /* ensure CD_MASK_BAREMESH for now */
BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL;
uint64_t data_mask = scene->customdata_mask | ob->customdata_mask | CD_MASK_BAREMESH;
uint64_t data_mask = scene->customdata_mask | CD_MASK_BAREMESH;
if (em) {
makeDerivedMesh(scene, ob, em, data_mask, 0); /* was CD_MASK_BAREMESH */
}

View File

@@ -297,7 +297,6 @@ bool ED_view3d_lock(struct RegionView3D *rv3d);
uint64_t ED_view3d_datamask(struct Scene *scene, struct View3D *v3d);
uint64_t ED_view3d_screen_datamask(struct bScreen *screen);
uint64_t ED_view3d_object_datamask(struct Scene *scene);
/* camera lock functions */
bool ED_view3d_camera_lock_check(struct View3D *v3d, struct RegionView3D *rv3d);

View File

@@ -145,7 +145,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
/* derivedMesh might be needed for solving parenting,
* so re-create it here */
makeDerivedMesh(scene, obedit, em, CD_MASK_BAREMESH, 0);
makeDerivedMesh(scene, obedit, em, CD_MASK_BAREMESH|CD_MASK_ORIGINDEX, 0);
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {

View File

@@ -407,8 +407,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op)
oglrender->rv3d = oglrender->ar->regiondata;
/* MUST be cleared on exit */
oglrender->scene->customdata_mask_modal = (ED_view3d_datamask(oglrender->scene, oglrender->v3d) |
ED_view3d_object_datamask(oglrender->scene));
oglrender->scene->customdata_mask_modal = ED_view3d_datamask(oglrender->scene, oglrender->v3d);
/* apply immediately in case we're rendering from a script,
* running notifiers again will overwrite */

View File

@@ -2498,33 +2498,6 @@ CustomDataMask ED_view3d_datamask(Scene *scene, View3D *v3d)
return mask;
}
CustomDataMask ED_view3d_object_datamask(Scene *scene)
{
Object *ob = scene->basact ? scene->basact->object : NULL;
CustomDataMask mask = 0;
if (ob) {
/* check if we need tfaces & mcols due to face select or texture paint */
if (paint_facesel_test(ob) || (ob->mode & OB_MODE_TEXTURE_PAINT)) {
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
}
/* check if we need mcols due to vertex paint or weightpaint */
if (ob->mode & OB_MODE_VERTEX_PAINT) {
mask |= CD_MASK_MCOL;
}
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
mask |= CD_MASK_PREVIEW_MCOL;
}
if (ob->mode & OB_MODE_EDIT)
mask |= CD_MASK_MVERT_SKIN;
}
return mask;
}
/* goes over all modes and view3d settings */
CustomDataMask ED_view3d_screen_datamask(bScreen *screen)
{
@@ -2539,8 +2512,6 @@ CustomDataMask ED_view3d_screen_datamask(bScreen *screen)
}
}
mask |= ED_view3d_object_datamask(scene);
return mask;
}