Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/paint_image_proj.c
| Show First 20 Lines • Show All 401 Lines • ▼ Show 20 Lines | #ifndef PROJ_DEBUG_NOSEAMBLEED | ||||
| LinkNode **vertFaces; | LinkNode **vertFaces; | ||||
| /** Seams per vert, to find adjacent seams. */ | /** Seams per vert, to find adjacent seams. */ | ||||
| ListBase *vertSeams; | ListBase *vertSeams; | ||||
| #endif | #endif | ||||
| SpinLock *tile_lock; | SpinLock *tile_lock; | ||||
| Mesh *me_eval; | Mesh *me_eval; | ||||
| bool me_eval_free; | |||||
| int totlooptri_eval; | int totlooptri_eval; | ||||
| int totloop_eval; | int totloop_eval; | ||||
| int totpoly_eval; | int totpoly_eval; | ||||
| int totedge_eval; | int totedge_eval; | ||||
| int totvert_eval; | int totvert_eval; | ||||
| const MVert *mvert_eval; | const MVert *mvert_eval; | ||||
| const MEdge *medge_eval; | const MEdge *medge_eval; | ||||
| ▲ Show 20 Lines • Show All 3,606 Lines • ▼ Show 20 Lines | static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *ps) | ||||
| Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); | Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); | ||||
| Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); | Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); | ||||
| if (scene_eval == NULL || ob_eval == NULL) { | if (scene_eval == NULL || ob_eval == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| CustomData_MeshMasks cddata_masks = scene_eval->customdata_mask; | CustomData_MeshMasks cddata_masks = scene_eval->customdata_mask; | ||||
| cddata_masks.fmask |= CD_MASK_MTFACE; | cddata_masks.fmask |= CD_MASK_MTFACE; | ||||
sergey: Does this work correctly if the mesh already had all the custom data layers in it?
Maybe state… | |||||
| cddata_masks.lmask |= CD_MASK_MLOOPUV; | cddata_masks.lmask |= CD_MASK_MLOOPUV; | ||||
| /* Workaround for subsurf selection, try the display mesh first */ | |||||
| if (ps->source == PROJ_SRC_IMAGE_CAM) { | |||||
| /* using render mesh, assume only camera was rendered from */ | |||||
| ps->me_eval = mesh_create_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks); | |||||
| ps->me_eval_free = true; | |||||
| } | |||||
| else { | |||||
| if (ps->do_face_sel) { | if (ps->do_face_sel) { | ||||
Not Done Inline Actionscreate always creates mesh, so you are the one who is responsible for freeing it. sergey: `create` always creates mesh, so you are the one who is responsible for freeing it. | |||||
| cddata_masks.vmask |= CD_MASK_ORIGINDEX; | cddata_masks.vmask |= CD_MASK_ORIGINDEX; | ||||
| cddata_masks.emask |= CD_MASK_ORIGINDEX; | cddata_masks.emask |= CD_MASK_ORIGINDEX; | ||||
| cddata_masks.pmask |= CD_MASK_ORIGINDEX; | cddata_masks.pmask |= CD_MASK_ORIGINDEX; | ||||
| } | } | ||||
| ps->me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks); | ps->me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks); | ||||
| ps->me_eval_free = false; | |||||
| } | |||||
| if (!CustomData_has_layer(&ps->me_eval->ldata, CD_MLOOPUV)) { | if (!CustomData_has_layer(&ps->me_eval->ldata, CD_MLOOPUV)) { | ||||
| if (ps->me_eval_free) { | |||||
| BKE_id_free(NULL, ps->me_eval); | |||||
| } | |||||
| ps->me_eval = NULL; | ps->me_eval = NULL; | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* Build final material array, we use this a lot here. */ | /* Build final material array, we use this a lot here. */ | ||||
| /* materials start from 1, default material is 0 */ | /* materials start from 1, default material is 0 */ | ||||
| const int totmat = ob->totcol + 1; | const int totmat = ob->totcol + 1; | ||||
| ps->mat_array = MEM_malloc_arrayN(totmat, sizeof(*ps->mat_array), __func__); | ps->mat_array = MEM_malloc_arrayN(totmat, sizeof(*ps->mat_array), __func__); | ||||
| ▲ Show 20 Lines • Show All 566 Lines • ▼ Show 20 Lines | if (ps->seam_bleed_px > 0.0f) { | ||||
| MEM_freeN(ps->vertSeams); | MEM_freeN(ps->vertSeams); | ||||
| } | } | ||||
| #endif | #endif | ||||
| if (ps->do_mask_cavity) { | if (ps->do_mask_cavity) { | ||||
| MEM_freeN(ps->cavities); | MEM_freeN(ps->cavities); | ||||
| } | } | ||||
| if (ps->me_eval_free) { | |||||
| BKE_id_free(NULL, ps->me_eval); | |||||
| } | |||||
| ps->me_eval = NULL; | ps->me_eval = NULL; | ||||
| } | } | ||||
| if (ps->blurkernel) { | if (ps->blurkernel) { | ||||
| paint_delete_blur_kernel(ps->blurkernel); | paint_delete_blur_kernel(ps->blurkernel); | ||||
Not Done Inline ActionsHow often project_paint_end is called? sergey: How often `project_paint_end` is called?
Tagging geometry for update in painting modes is… | |||||
| MEM_freeN(ps->blurkernel); | MEM_freeN(ps->blurkernel); | ||||
| } | } | ||||
| if (ps->vertFlags) { | if (ps->vertFlags) { | ||||
| MEM_freeN(ps->vertFlags); | MEM_freeN(ps->vertFlags); | ||||
| } | } | ||||
| for (a = 0; a < ps->thread_tot; a++) { | for (a = 0; a < ps->thread_tot; a++) { | ||||
| ▲ Show 20 Lines • Show All 2,137 Lines • Show Last 20 Lines | |||||
Does this work correctly if the mesh already had all the custom data layers in it?
Maybe state explicitly in the comment to BKE_object_eval_reset() what happens in this case.
And maybe look into avoiding mesh re-evaluation here if it has all the data already. Could be done by making it so mesh_get_eval_final() does re-set prior to re-evaluation (as re-evaluation without reset is meaningless anyway).