Changeset View
Standalone View
source/blender/blenkernel/intern/multires.c
| Show First 20 Lines • Show All 269 Lines • ▼ Show 20 Lines | for (j = 0; j < me->mpoly[i].totloop; j++) { | ||||
| md->hidden = BLI_BITMAP_NEW(gridarea, "MDisps.hidden initialize"); | md->hidden = BLI_BITMAP_NEW(gridarea, "MDisps.hidden initialize"); | ||||
| BLI_bitmap_set_all(md->hidden, true, gridarea); | BLI_bitmap_set_all(md->hidden, true, gridarea); | ||||
| } | } | ||||
| } | } | ||||
| return mdisps; | return mdisps; | ||||
| } | } | ||||
| Mesh *BKE_multires_create_mesh(struct Depsgraph *depsgraph, | Mesh *BKE_multires_create_mesh_from_base(struct Depsgraph *depsgraph, | ||||
| Object *object, | |||||
| MultiresModifierData *mmd) | |||||
| { | |||||
| Object *object_eval = DEG_get_evaluated_object(depsgraph, object); | |||||
| Mesh *base_mesh = object_eval->runtime.data_orig != NULL ? (ID *)object_eval->runtime.data_orig : | |||||
| (Mesh *)object->data; | |||||
| ModifierEvalContext modifier_ctx = { | |||||
| .depsgraph = depsgraph, | |||||
| .object = object_eval, | |||||
sergey: Should be something more like
Object *object_eval = DEG_get_evaluated_object(depsgraph… | |||||
Done Inline ActionsWithout MOD_APPLY_ORCO the mesh disappears after delete lower pablodp606: Without MOD_APPLY_ORCO the mesh disappears after delete lower | |||||
| .flag = MOD_APPLY_ORCO, | |||||
| }; | |||||
Done Inline ActionsThis function was renamed to BKE_modifier_get_info. sergey: This function was renamed to `BKE_modifier_get_info`. | |||||
| const ModifierTypeInfo *mti = BKE_modifier_get_info(mmd->modifier.type); | |||||
| Mesh *result = mti->modifyMesh(&mmd->modifier, &modifier_ctx, base_mesh); | |||||
| if (result == base_mesh) { | |||||
| result = BKE_mesh_copy_for_eval(base_mesh, true); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| Mesh *BKE_multires_create_mesh_from_deform(struct Depsgraph *depsgraph, | |||||
| Object *object, | Object *object, | ||||
| MultiresModifierData *mmd) | MultiresModifierData *mmd) | ||||
| { | { | ||||
| Object *object_eval = DEG_get_evaluated_object(depsgraph, object); | Object *object_eval = DEG_get_evaluated_object(depsgraph, object); | ||||
| Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); | Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); | ||||
| Mesh *deformed_mesh = mesh_get_eval_deform( | Mesh *deformed_mesh = mesh_get_eval_deform( | ||||
| depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH); | depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH); | ||||
| ModifierEvalContext modifier_ctx = { | ModifierEvalContext modifier_ctx = { | ||||
| .depsgraph = depsgraph, | .depsgraph = depsgraph, | ||||
| .object = object_eval, | .object = object_eval, | ||||
| ▲ Show 20 Lines • Show All 405 Lines • ▼ Show 20 Lines | if (level < gpm->level) { | ||||
| } | } | ||||
| MEM_freeN(gpm->data); | MEM_freeN(gpm->data); | ||||
| gpm->data = data; | gpm->data = data; | ||||
| gpm->level = level; | gpm->level = level; | ||||
| } | } | ||||
| } | } | ||||
| static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) | static void multires_delete_higher(MultiresModifierData *mmd, Object *ob, int lvl) | ||||
| { | { | ||||
| Mesh *me = (Mesh *)ob->data; | Mesh *me = (Mesh *)ob->data; | ||||
| int levels = mmd->totlvl - lvl; | int levels = mmd->totlvl - lvl; | ||||
| MDisps *mdisps; | MDisps *mdisps; | ||||
| GridPaintMask *gpm; | GridPaintMask *gpm; | ||||
| multires_set_tot_mdisps(me, mmd->totlvl); | multires_set_tot_mdisps(me, mmd->totlvl); | ||||
| multiresModifier_ensure_external_read(me, mmd); | multiresModifier_ensure_external_read(me, mmd); | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | if (mdisps && levels > 0) { | ||||
| else { | else { | ||||
| multires_customdata_delete(me); | multires_customdata_delete(me); | ||||
| } | } | ||||
| } | } | ||||
| multires_set_tot_level(ob, mmd, lvl); | multires_set_tot_level(ob, mmd, lvl); | ||||
| } | } | ||||
| /* (direction = 1) for delete higher, (direction = 0) for lower (not implemented yet) */ | static void multires_delete_lower(Depsgraph *depsgraph, | ||||
| void multiresModifier_del_levels(MultiresModifierData *mmd, | MultiresModifierData *mmd, | ||||
| Scene *scene, | |||||
| Object *ob, | Object *ob, | ||||
| int direction) | int lvl) | ||||
| { | |||||
| Mesh *base_mesh = BKE_mesh_from_object(ob); | |||||
| /* Switch Multires to the higher level. */ | |||||
| mmd->lvl = mmd->sculptlvl = mmd->totlvl; | |||||
| /* Get a new mesh with the higher subdivision level applied and set it as base mesh. */ | |||||
| Mesh *subdiv_mesh = BKE_multires_create_mesh_from_base(depsgraph, ob, mmd); | |||||
| BKE_mesh_nomain_to_mesh(subdiv_mesh, base_mesh, ob, &CD_MASK_MESH, true); | |||||
Done Inline Actions@Sergey Sharybin (sergey) I tried to find the deformation bug again. If I remove everything from here (the unsubdivide step), so the operator only sets the base mesh of the object to subdiv_mesh, it appears as deformed. That is expected, right? pablodp606: @sergey I tried to find the deformation bug again. If I remove everything from here (the… | |||||
Not Done Inline ActionsA bit hard to give definitive answer. Can you share patch with the removal and .blend file, so we are sure we are talking about same thing? Also, did you test unsubdivide operator with deform modifier prior to the multires? sergey: A bit hard to give definitive answer. Can you share patch with the removal and .blend file, so… | |||||
| /* Unsubdivide the mesh level_difference times to get a new base mesh without the lower | |||||
| * levels. */ | |||||
| const int level_difference = mmd->totlvl - lvl; | |||||
| multires_set_tot_level(ob, mmd, 0); | |||||
| const int levels_rebuild = multiresModifier_rebuild_subdiv( | |||||
Done Inline ActionsSubtract the number of removed layers rather than assigning to zero, so that render look stays the same even if you had preview levels set to a lower value than final render. sergey: Subtract the number of removed layers rather than assigning to zero, so that render look stays… | |||||
| depsgraph, ob, mmd, level_difference, true); | |||||
| mmd->renderlvl -= levels_rebuild; | |||||
| } | |||||
| void multiresModifier_delete_levels_higher(MultiresModifierData *mmd, Scene *scene, Object *ob) | |||||
| { | { | ||||
| Mesh *me = BKE_mesh_from_object(ob); | Mesh *me = BKE_mesh_from_object(ob); | ||||
| int lvl = multires_get_level(scene, ob, mmd, false, true); | int lvl = multires_get_level(scene, ob, mmd, false, true); | ||||
| int levels = mmd->totlvl - lvl; | int levels = mmd->totlvl - lvl; | ||||
| MDisps *mdisps; | MDisps *mdisps; | ||||
| multires_set_tot_mdisps(me, mmd->totlvl); | multires_set_tot_mdisps(me, mmd->totlvl); | ||||
| multiresModifier_ensure_external_read(me, mmd); | multiresModifier_ensure_external_read(me, mmd); | ||||
| mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); | mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); | ||||
| multires_force_sculpt_rebuild(ob); | multires_force_sculpt_rebuild(ob); | ||||
| if (mdisps && levels > 0 && direction == 1) { | if (mdisps && levels > 0) { | ||||
| multires_del_higher(mmd, ob, lvl); | multires_delete_higher(mmd, ob, lvl); | ||||
| multires_set_tot_level(ob, mmd, lvl); | |||||
| } | |||||
| } | } | ||||
| multires_set_tot_level(ob, mmd, lvl); | void multiresModifier_delete_levels_lower(Depsgraph *depsgraph, | ||||
| MultiresModifierData *mmd, | |||||
| Scene *scene, | |||||
| Object *ob) | |||||
| { | |||||
| Mesh *me = BKE_mesh_from_object(ob); | |||||
| int lvl = multires_get_level(scene, ob, mmd, false, true); | |||||
| MDisps *mdisps; | |||||
| multires_set_tot_mdisps(me, mmd->totlvl); | |||||
| multiresModifier_ensure_external_read(me, mmd); | |||||
| mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); | |||||
| multires_force_sculpt_rebuild(ob); | |||||
| if (mdisps && lvl > 0) { | |||||
| multires_delete_lower(depsgraph, mmd, ob, lvl); | |||||
| } | |||||
| } | } | ||||
| static DerivedMesh *multires_dm_create_local(Scene *scene, | static DerivedMesh *multires_dm_create_local(Scene *scene, | ||||
| Object *ob, | Object *ob, | ||||
| DerivedMesh *dm, | DerivedMesh *dm, | ||||
| int lvl, | int lvl, | ||||
| int totlvl, | int totlvl, | ||||
| int simple, | int simple, | ||||
| ▲ Show 20 Lines • Show All 1,446 Lines • ▼ Show 20 Lines | if (mmd_dst->simple) { | ||||
| ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_SIMPLE); | ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_SIMPLE); | ||||
| } | } | ||||
| else { | else { | ||||
| multiresModifier_subdivide_to_level( | multiresModifier_subdivide_to_level( | ||||
| ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_CATMULL_CLARK); | ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_CATMULL_CLARK); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| multires_del_higher(mmd_dst, ob_dst, mmd_src->totlvl); | multires_delete_higher(mmd_dst, ob_dst, mmd_src->totlvl); | ||||
| } | } | ||||
| } | } | ||||
| static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst) | static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst) | ||||
| { | { | ||||
| MultiresModifierData *mmd_src = get_multires_modifier(scene, ob_src, true); | MultiresModifierData *mmd_src = get_multires_modifier(scene, ob_src, true); | ||||
| MultiresModifierData *mmd_dst = get_multires_modifier(scene, ob_dst, true); | MultiresModifierData *mmd_dst = get_multires_modifier(scene, ob_dst, true); | ||||
| ▲ Show 20 Lines • Show All 270 Lines • Show Last 20 Lines | |||||
Should be something more like
Object *object_eval = DEG_get_evaluated_object(depsgraph, object); Mesh *base_mesh = (ID *)object_eval->runtime.data_orig; ModifierEvalContext modifier_ctx = { .depsgraph = depsgraph, .object = object_eval, .flag = MOD_APPLY_ORCO, };Maybe check for data_orig != NULL and if it's NULL use object->data.
Also, why do you need MOD_APPLY_ORCO and why do you need to take Scene Simplify into account here?