diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_image_proj.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_image_proj.c | 570 |
1 files changed, 226 insertions, 344 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 44da12c13e5..bbf1da2d584 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -58,6 +58,7 @@ #include "DNA_brush_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" @@ -65,8 +66,6 @@ #include "BKE_colorband.h" #include "BKE_context.h" #include "BKE_colortools.h" -#include "BKE_depsgraph.h" -#include "BKE_DerivedMesh.h" #include "BKE_idprop.h" #include "BKE_brush.h" #include "BKE_image.h" @@ -75,12 +74,16 @@ #include "BKE_material.h" #include "BKE_mesh.h" #include "BKE_mesh_mapping.h" +#include "BKE_mesh_runtime.h" #include "BKE_node.h" #include "BKE_paint.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_texture.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + #include "UI_interface.h" #include "ED_object.h" @@ -227,6 +230,7 @@ typedef struct ProjPaintState { View3D *v3d; RegionView3D *rv3d; ARegion *ar; + Depsgraph *depsgraph; Scene *scene; int source; /* PROJ_SRC_**** */ @@ -282,7 +286,6 @@ typedef struct ProjPaintState { bool do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */ bool do_mask_normal; /* mask out pixels based on their normals */ bool do_mask_cavity; /* mask out pixels based on cavity */ - bool do_new_shading_nodes; /* cache BKE_scene_use_new_shading_nodes value */ float normal_angle; /* what angle to mask at */ float normal_angle__cos; /* cos(normal_angle), faster to compare */ float normal_angle_inner; @@ -351,28 +354,30 @@ typedef struct ProjPaintState { SpinLock *tile_lock; - DerivedMesh *dm; - int dm_totlooptri; - int dm_totpoly; - int dm_totedge; - int dm_totvert; - bool dm_release; + Mesh *me_eval; + int totlooptri_eval; + int totpoly_eval; + int totedge_eval; + int totvert_eval; - const MVert *dm_mvert; - const MEdge *dm_medge; - const MPoly *dm_mpoly; - const MLoop *dm_mloop; - const MLoopTri *dm_mlooptri; + const MVert *mvert_eval; + const MEdge *medge_eval; + const MPoly *mpoly_eval; + const MLoop *mloop_eval; + const MLoopTri *mlooptri_eval; - const MLoopUV *dm_mloopuv_stencil; + const MLoopUV *mloopuv_stencil_eval; /** - * \note These UV layers are aligned to \a dm_mpoly + * \note These UV layers are aligned to \a mpoly_eval * but each pointer references the start of the layer, * so a loop indirection is needed as well. */ - const MLoopUV **dm_mloopuv; - const MLoopUV **dm_mloopuv_clone; /* other UV map, use for cloning between layers */ + const MLoopUV **poly_to_loop_uv; + const MLoopUV **poly_to_loop_uv_clone; /* other UV map, use for cloning between layers */ + + /* Actual material for each index, either from object or Mesh datablock... */ + Material **mat_array; bool use_colormanagement; } ProjPaintState; @@ -438,13 +443,13 @@ typedef struct { BLI_INLINE const MPoly *ps_tri_index_to_mpoly(const ProjPaintState *ps, int tri_index) { - return &ps->dm_mpoly[ps->dm_mlooptri[tri_index].poly]; + return &ps->mpoly_eval[ps->mlooptri_eval[tri_index].poly]; } #define PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) \ - ps->dm_mloop[lt->tri[0]].v, \ - ps->dm_mloop[lt->tri[1]].v, \ - ps->dm_mloop[lt->tri[2]].v, + ps->mloop_eval[lt->tri[0]].v, \ + ps->mloop_eval[lt->tri[1]].v, \ + ps->mloop_eval[lt->tri[2]].v, #define PS_LOOPTRI_AS_UV_3(uvlayer, lt) \ uvlayer[lt->poly][lt->tri[0]].uv, \ @@ -466,7 +471,7 @@ BLI_INLINE const MPoly *ps_tri_index_to_mpoly(const ProjPaintState *ps, int tri_ static TexPaintSlot *project_paint_face_paint_slot(const ProjPaintState *ps, int tri_index) { const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index); - Material *ma = ps->dm->mat[mp->mat_nr]; + Material *ma = ps->mat_array[mp->mat_nr]; return ma ? ma->texpaintslot + ma->paint_active_slot : NULL; } @@ -477,7 +482,7 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int tri_i } else { const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index); - Material *ma = ps->dm->mat[mp->mat_nr]; + Material *ma = ps->mat_array[mp->mat_nr]; TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_active_slot : NULL; return slot ? slot->ima : ps->canvas_ima; } @@ -486,14 +491,14 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int tri_i static TexPaintSlot *project_paint_face_clone_slot(const ProjPaintState *ps, int tri_index) { const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index); - Material *ma = ps->dm->mat[mp->mat_nr]; + Material *ma = ps->mat_array[mp->mat_nr]; return ma ? ma->texpaintslot + ma->paint_clone_slot : NULL; } static Image *project_paint_face_clone_image(const ProjPaintState *ps, int tri_index) { const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index); - Material *ma = ps->dm->mat[mp->mat_nr]; + Material *ma = ps->mat_array[mp->mat_nr]; TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_clone_slot : NULL; return slot ? slot->ima : ps->clone_ima; } @@ -594,11 +599,11 @@ static int project_paint_PickFace( for (node = ps->bucketFaces[bucket_index]; node; node = node->next) { const int tri_index = GET_INT_FROM_POINTER(node->link); - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const float *vtri_ss[3] = { - ps->screenCoords[ps->dm_mloop[lt->tri[0]].v], - ps->screenCoords[ps->dm_mloop[lt->tri[1]].v], - ps->screenCoords[ps->dm_mloop[lt->tri[2]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[0]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[1]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[2]].v], }; @@ -653,8 +658,8 @@ static bool project_paint_PickColor( if (tri_index == -1) return 0; - lt = &ps->dm_mlooptri[tri_index]; - PS_LOOPTRI_ASSIGN_UV_3(lt_tri_uv, ps->dm_mloopuv, lt); + lt = &ps->mlooptri_eval[tri_index]; + PS_LOOPTRI_ASSIGN_UV_3(lt_tri_uv, ps->poly_to_loop_uv, lt); interp_v2_v2v2v2(uv, UNPACK3(lt_tri_uv), w); @@ -810,19 +815,19 @@ static bool project_bucket_point_occluded( const int tri_index = GET_INT_FROM_POINTER(bucketFace->link); if (orig_face != tri_index) { - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const float *vtri_ss[3] = { - ps->screenCoords[ps->dm_mloop[lt->tri[0]].v], - ps->screenCoords[ps->dm_mloop[lt->tri[1]].v], - ps->screenCoords[ps->dm_mloop[lt->tri[2]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[0]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[1]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[2]].v], }; float w[3]; if (do_clip) { const float *vtri_co[3] = { - ps->dm_mvert[ps->dm_mloop[lt->tri[0]].v].co, - ps->dm_mvert[ps->dm_mloop[lt->tri[1]].v].co, - ps->dm_mvert[ps->dm_mloop[lt->tri[2]].v].co, + ps->mvert_eval[ps->mloop_eval[lt->tri[0]].v].co, + ps->mvert_eval[ps->mloop_eval[lt->tri[1]].v].co, + ps->mvert_eval[ps->mloop_eval[lt->tri[2]].v].co, }; isect_ret = project_paint_occlude_ptv_clip( pixelScreenCo, UNPACK3(vtri_ss), UNPACK3(vtri_co), @@ -1002,8 +1007,8 @@ static bool pixel_bounds_array(float (*uv)[2], rcti *bounds_px, const int ibuf_x static void project_face_winding_init(const ProjPaintState *ps, const int tri_index) { /* detect the winding of faces in uv space */ - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; - const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv, lt) }; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; + const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt) }; float winding = cross_tri_v2(lt_tri_uv[0], lt_tri_uv[1], lt_tri_uv[2]); if (winding > 0) @@ -1019,11 +1024,11 @@ static bool check_seam( const int orig_face, const int orig_i1_fidx, const int orig_i2_fidx, int *other_face, int *orig_fidx) { - const MLoopTri *orig_lt = &ps->dm_mlooptri[orig_face]; - const float *orig_lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv, orig_lt) }; + const MLoopTri *orig_lt = &ps->mlooptri_eval[orig_face]; + const float *orig_lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, orig_lt) }; /* vert indices from face vert order indices */ - const unsigned int i1 = ps->dm_mloop[orig_lt->tri[orig_i1_fidx]].v; - const unsigned int i2 = ps->dm_mloop[orig_lt->tri[orig_i2_fidx]].v; + const unsigned int i1 = ps->mloop_eval[orig_lt->tri[orig_i1_fidx]].v; + const unsigned int i2 = ps->mloop_eval[orig_lt->tri[orig_i2_fidx]].v; LinkNode *node; int i1_fidx = -1, i2_fidx = -1; /* index in face */ @@ -1031,7 +1036,7 @@ static bool check_seam( const int tri_index = GET_INT_FROM_POINTER(node->link); if (tri_index != orig_face) { - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) }; /* could check if the 2 faces images match here, * but then there wouldn't be a way to return the opposite face's info */ @@ -1044,7 +1049,7 @@ static bool check_seam( /* Only need to check if 'i2_fidx' is valid because we know i1_fidx is the same vert on both faces */ if (i2_fidx != -1) { - const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv, lt) }; + const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt) }; Image *tpage = project_paint_face_paint_image(ps, tri_index); Image *orig_tpage = project_paint_face_paint_image(ps, orig_face); @@ -1348,8 +1353,8 @@ static float project_paint_uvpixel_mask( Image *other_tpage = ps->stencil_ima; if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) { - const MLoopTri *lt_other = &ps->dm_mlooptri[tri_index]; - const float *lt_other_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv, lt_other) }; + const MLoopTri *lt_other = &ps->mlooptri_eval[tri_index]; + const float *lt_other_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt_other) }; /* BKE_image_acquire_ibuf - TODO - this may be slow */ unsigned char rgba_ub[4]; @@ -1382,7 +1387,7 @@ static float project_paint_uvpixel_mask( } if (ps->do_mask_cavity) { - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) }; float ca1, ca2, ca3, ca_mask; ca1 = ps->cavities[lt_vtri[0]]; @@ -1397,16 +1402,16 @@ static float project_paint_uvpixel_mask( /* calculate mask */ if (ps->do_mask_normal) { - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) }; - const MPoly *mp = &ps->dm_mpoly[lt->poly]; + const MPoly *mp = &ps->mpoly_eval[lt->poly]; float no[3], angle_cos; if (mp->flag & ME_SMOOTH) { const short *no1, *no2, *no3; - no1 = ps->dm_mvert[lt_vtri[0]].no; - no2 = ps->dm_mvert[lt_vtri[1]].no; - no3 = ps->dm_mvert[lt_vtri[2]].no; + no1 = ps->mvert_eval[lt_vtri[0]].no; + no2 = ps->mvert_eval[lt_vtri[1]].no; + no3 = ps->mvert_eval[lt_vtri[2]].no; no[0] = w[0] * no1[0] + w[1] * no2[0] + w[2] * no3[0]; no[1] = w[0] * no1[1] + w[1] * no2[1] + w[2] * no3[1]; @@ -1418,9 +1423,9 @@ static float project_paint_uvpixel_mask( #if 1 /* normalizing per pixel isn't optimal, we could cache or check ps->*/ normal_tri_v3(no, - ps->dm_mvert[lt_vtri[0]].co, - ps->dm_mvert[lt_vtri[1]].co, - ps->dm_mvert[lt_vtri[2]].co); + ps->mvert_eval[lt_vtri[0]].co, + ps->mvert_eval[lt_vtri[1]].co, + ps->mvert_eval[lt_vtri[2]].co); #else /* don't use because some modifiers dont have normal data (subsurf for eg) */ copy_v3_v3(no, (float *)ps->dm->getTessFaceData(ps->dm, tri_index, CD_NORMAL)); @@ -1439,9 +1444,9 @@ static float project_paint_uvpixel_mask( /* Annoying but for the perspective view we need to get the pixels location in 3D space :/ */ float viewDirPersp[3]; const float *co1, *co2, *co3; - co1 = ps->dm_mvert[lt_vtri[0]].co; - co2 = ps->dm_mvert[lt_vtri[1]].co; - co3 = ps->dm_mvert[lt_vtri[2]].co; + co1 = ps->mvert_eval[lt_vtri[0]].co; + co2 = ps->mvert_eval[lt_vtri[1]].co; + co3 = ps->mvert_eval[lt_vtri[2]].co; /* Get the direction from the viewPoint to the pixel and normalize */ viewDirPersp[0] = (ps->viewPos[0] - (w[0] * co1[0] + w[1] * co2[0] + w[2] * co3[0])); @@ -1610,13 +1615,13 @@ static ProjPixel *project_paint_uvpixel_init( /* done with view3d_project_float inline */ if (ps->tool == PAINT_TOOL_CLONE) { - if (ps->dm_mloopuv_clone) { + if (ps->poly_to_loop_uv_clone) { ImBuf *ibuf_other; Image *other_tpage = project_paint_face_clone_image(ps, tri_index); if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) { - const MLoopTri *lt_other = &ps->dm_mlooptri[tri_index]; - const float *lt_other_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv_clone, lt_other) }; + const MLoopTri *lt_other = &ps->mlooptri_eval[tri_index]; + const float *lt_other_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv_clone, lt_other) }; /* BKE_image_acquire_ibuf - TODO - this may be slow */ @@ -2491,8 +2496,7 @@ static bool IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot static void project_paint_face_init( const ProjPaintState *ps, const int thread_index, const int bucket_index, const int tri_index, const int image_index, - const rctf *clip_rect, const rctf *bucket_bounds, ImBuf *ibuf, ImBuf **tmpibuf, - const bool clamp_u, const bool clamp_v) + const rctf *clip_rect, const rctf *bucket_bounds, ImBuf *ibuf, ImBuf **tmpibuf) { /* Projection vars, to get the 3D locations into screen space */ MemArena *arena = ps->arena_mt[thread_index]; @@ -2508,9 +2512,9 @@ static void project_paint_face_init( ps->projImages + image_index }; - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) }; - const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv, lt) }; + const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt) }; /* UV/pixel seeking data */ int x; /* Image X-Pixel */ @@ -2544,9 +2548,9 @@ static void project_paint_face_init( const bool do_backfacecull = ps->do_backfacecull; const bool do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0; - vCo[0] = ps->dm_mvert[lt_vtri[0]].co; - vCo[1] = ps->dm_mvert[lt_vtri[1]].co; - vCo[2] = ps->dm_mvert[lt_vtri[2]].co; + vCo[0] = ps->mvert_eval[lt_vtri[0]].co; + vCo[1] = ps->mvert_eval[lt_vtri[1]].co; + vCo[2] = ps->mvert_eval[lt_vtri[2]].co; /* Use lt_uv_pxoffset instead of lt_tri_uv so we can offset the UV half a pixel @@ -2599,17 +2603,6 @@ static void project_paint_face_init( #endif if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) { - - if (clamp_u) { - CLAMP(bounds_px.xmin, 0, ibuf->x); - CLAMP(bounds_px.xmax, 0, ibuf->x); - } - - if (clamp_v) { - CLAMP(bounds_px.ymin, 0, ibuf->y); - CLAMP(bounds_px.ymax, 0, ibuf->y); - } - #if 0 project_paint_undo_tiles_init(&bounds_px, ps->projImages + image_index, tmpibuf, tile_width, threaded, ps->do_masking); @@ -2641,9 +2634,9 @@ static void project_paint_face_init( if (do_clip || do_3d_mapping) { interp_v3_v3v3v3( wco, - ps->dm_mvert[lt_vtri[0]].co, - ps->dm_mvert[lt_vtri[1]].co, - ps->dm_mvert[lt_vtri[2]].co, + ps->mvert_eval[lt_vtri[0]].co, + ps->mvert_eval[lt_vtri[1]].co, + ps->mvert_eval[lt_vtri[2]].co, w); if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, true)) { continue; /* Watch out that no code below this needs to run */ @@ -2823,7 +2816,7 @@ static void project_paint_face_init( !project_bucket_point_occluded(ps, bucketFaceNodes, tri_index, pixelScreenCo)) { /* Only bother calculating the weights if we intersect */ - if (ps->do_mask_normal || ps->dm_mloopuv_clone) { + if (ps->do_mask_normal || ps->poly_to_loop_uv_clone) { const float uv_fac = fac1 + (fac * (fac2 - fac1)); #if 0 /* get the UV on the line since we want to copy the pixels from there for bleeding */ @@ -2926,19 +2919,16 @@ static void project_bucket_init( int tri_index, image_index = 0; ImBuf *ibuf = NULL; Image *tpage_last = NULL, *tpage; - Image *ima = NULL; ImBuf *tmpibuf = NULL; if (ps->image_tot == 1) { /* Simple loop, no context switching */ ibuf = ps->projImages[0].ibuf; - ima = ps->projImages[0].ima; for (node = ps->bucketFaces[bucket_index]; node; node = node->next) { project_paint_face_init( ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0, - clip_rect, bucket_bounds, ibuf, &tmpibuf, - (ima->tpageflag & IMA_CLAMP_U) != 0, (ima->tpageflag & IMA_CLAMP_V) != 0); + clip_rect, bucket_bounds, ibuf, &tmpibuf); } } else { @@ -2955,7 +2945,6 @@ static void project_bucket_init( for (image_index = 0; image_index < ps->image_tot; image_index++) { if (ps->projImages[image_index].ima == tpage_last) { ibuf = ps->projImages[image_index].ibuf; - ima = ps->projImages[image_index].ima; break; } } @@ -2964,8 +2953,7 @@ static void project_bucket_init( project_paint_face_init( ps, thread_index, bucket_index, tri_index, image_index, - clip_rect, bucket_bounds, ibuf, &tmpibuf, - (ima->tpageflag & IMA_CLAMP_U) != 0, (ima->tpageflag & IMA_CLAMP_V) != 0); + clip_rect, bucket_bounds, ibuf, &tmpibuf); } } @@ -3081,26 +3069,8 @@ static void project_paint_delayed_face_init(ProjPaintState *ps, const MLoopTri * #endif } -/** - * \note when using subsurf or multires, some arrays are thrown away, we need to keep a copy - */ -static void proj_paint_state_non_cddm_init(ProjPaintState *ps) -{ - if (ps->dm->type != DM_TYPE_CDDM) { - ps->dm_mvert = MEM_dupallocN(ps->dm_mvert); - ps->dm_mpoly = MEM_dupallocN(ps->dm_mpoly); - ps->dm_mloop = MEM_dupallocN(ps->dm_mloop); - /* looks like these are ok for now.*/ -#if 0 - ps->dm_mloopuv = MEM_dupallocN(ps->dm_mloopuv); - ps->dm_mloopuv_clone = MEM_dupallocN(ps->dm_mloopuv_clone); - ps->dm_mloopuv_stencil = MEM_dupallocN(ps->dm_mloopuv_stencil); -#endif - } -} - static void proj_paint_state_viewport_init( - ProjPaintState *ps, const char symmetry_flag) + ProjPaintState *ps, const Depsgraph *depsgraph, const char symmetry_flag) { float mat[3][3]; float viewmat[4][4]; @@ -3134,7 +3104,7 @@ static void proj_paint_state_viewport_init( ED_view3d_ob_project_mat_get_from_obmat(ps->rv3d, ps->obmat, ps->projectMat); - ps->is_ortho = ED_view3d_clip_range_get(ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend, true); + ps->is_ortho = ED_view3d_clip_range_get(ps->depsgraph, ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend, true); } else { /* re-projection */ @@ -3161,17 +3131,17 @@ static void proj_paint_state_viewport_init( invert_m4_m4(viewinv, viewmat); } else if (ps->source == PROJ_SRC_IMAGE_CAM) { - Object *cam_ob = ps->scene->camera; + Object *cam_ob_eval = DEG_get_evaluated_object(depsgraph, ps->scene->camera); CameraParams params; /* viewmat & viewinv */ - copy_m4_m4(viewinv, cam_ob->obmat); + copy_m4_m4(viewinv, cam_ob_eval->obmat); normalize_m4(viewinv); invert_m4_m4(viewmat, viewinv); /* window matrix, clipping and ortho */ BKE_camera_params_init(¶ms); - BKE_camera_params_from_object(¶ms, cam_ob); + BKE_camera_params_from_object(¶ms, cam_ob_eval); BKE_camera_params_compute_viewplane(¶ms, ps->winx, ps->winy, 1.0f, 1.0f); BKE_camera_params_compute_matrix(¶ms); @@ -3218,11 +3188,11 @@ static void proj_paint_state_screen_coords_init(ProjPaintState *ps, const int di INIT_MINMAX2(ps->screenMin, ps->screenMax); - ps->screenCoords = MEM_mallocN(sizeof(float) * ps->dm_totvert * 4, "ProjectPaint ScreenVerts"); + ps->screenCoords = MEM_mallocN(sizeof(float) * ps->totvert_eval * 4, "ProjectPaint ScreenVerts"); projScreenCo = *ps->screenCoords; if (ps->is_ortho) { - for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) { + for (a = 0, mv = ps->mvert_eval; a < ps->totvert_eval; a++, mv++, projScreenCo += 4) { mul_v3_m4v3(projScreenCo, ps->projectMat, mv->co); /* screen space, not clamped */ @@ -3232,7 +3202,7 @@ static void proj_paint_state_screen_coords_init(ProjPaintState *ps, const int di } } else { - for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) { + for (a = 0, mv = ps->mvert_eval; a < ps->totvert_eval; a++, mv++, projScreenCo += 4) { copy_v3_v3(projScreenCo, mv->co); projScreenCo[3] = 1.0f; @@ -3293,21 +3263,21 @@ static void proj_paint_state_cavity_init(ProjPaintState *ps) int a; if (ps->do_mask_cavity) { - int *counter = MEM_callocN(sizeof(int) * ps->dm_totvert, "counter"); - float (*edges)[3] = MEM_callocN(sizeof(float) * 3 * ps->dm_totvert, "edges"); - ps->cavities = MEM_mallocN(sizeof(float) * ps->dm_totvert, "ProjectPaint Cavities"); + int *counter = MEM_callocN(sizeof(int) * ps->totvert_eval, "counter"); + float (*edges)[3] = MEM_callocN(sizeof(float) * 3 * ps->totvert_eval, "edges"); + ps->cavities = MEM_mallocN(sizeof(float) * ps->totvert_eval, "ProjectPaint Cavities"); cavities = ps->cavities; - for (a = 0, me = ps->dm_medge; a < ps->dm_totedge; a++, me++) { + for (a = 0, me = ps->medge_eval; a < ps->totedge_eval; a++, me++) { float e[3]; - sub_v3_v3v3(e, ps->dm_mvert[me->v1].co, ps->dm_mvert[me->v2].co); + sub_v3_v3v3(e, ps->mvert_eval[me->v1].co, ps->mvert_eval[me->v2].co); normalize_v3(e); add_v3_v3(edges[me->v2], e); counter[me->v2]++; sub_v3_v3(edges[me->v1], e); counter[me->v1]++; } - for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++) { + for (a = 0, mv = ps->mvert_eval; a < ps->totvert_eval; a++, mv++) { if (counter[a] > 0) { float no[3]; mul_v3_fl(edges[a], 1.0f / counter[a]); @@ -3328,10 +3298,10 @@ static void proj_paint_state_cavity_init(ProjPaintState *ps) static void proj_paint_state_seam_bleed_init(ProjPaintState *ps) { if (ps->seam_bleed_px > 0.0f) { - ps->vertFaces = MEM_callocN(sizeof(LinkNode *) * ps->dm_totvert, "paint-vertFaces"); - ps->faceSeamFlags = MEM_callocN(sizeof(char) * ps->dm_totlooptri, "paint-faceSeamFlags"); - ps->faceWindingFlags = MEM_callocN(sizeof(char) * ps->dm_totlooptri, "paint-faceWindindFlags"); - ps->faceSeamUVs = MEM_mallocN(sizeof(float[3][2]) * ps->dm_totlooptri, "paint-faceSeamUVs"); + ps->vertFaces = MEM_callocN(sizeof(LinkNode *) * ps->totvert_eval, "paint-vertFaces"); + ps->faceSeamFlags = MEM_callocN(sizeof(char) * ps->totlooptri_eval, "paint-faceSeamFlags"); + ps->faceWindingFlags = MEM_callocN(sizeof(char) * ps->totlooptri_eval, "paint-faceWindindFlags"); + ps->faceSeamUVs = MEM_mallocN(sizeof(float[3][2]) * ps->totlooptri_eval, "paint-faceSeamUVs"); } } #endif @@ -3375,9 +3345,9 @@ static void proj_paint_state_vert_flags_init(ProjPaintState *ps) float no[3]; int a; - ps->vertFlags = MEM_callocN(sizeof(char) * ps->dm_totvert, "paint-vertFlags"); + ps->vertFlags = MEM_callocN(sizeof(char) * ps->totvert_eval, "paint-vertFlags"); - for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++) { + for (a = 0, mv = ps->mvert_eval; a < ps->totvert_eval; a++, mv++) { normal_short_to_float_v3(no, mv->no); if (UNLIKELY(ps->is_flip_object)) { negate_v3(no); @@ -3422,49 +3392,63 @@ static void project_paint_bleed_add_face_user( } #endif -/* Return true if DM can be painted on, false otherwise */ -static bool proj_paint_state_dm_init(ProjPaintState *ps) +/* Return true if evaluated mesh can be painted on, false otherwise */ +static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *ps) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); + Scene *sce = ps->scene; + Object *ob = ps->ob; + /* Workaround for subsurf selection, try the display mesh first */ + /* XXX Don't think this is easily doable with new system, and not sure why that was needed in the first place :/ */ +#if 0 if (ps->source == PROJ_SRC_IMAGE_CAM) { /* using render mesh, assume only camera was rendered from */ - ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MLOOPUV | CD_MASK_MTFACE); + ps->dm = mesh_create_derived_render( + depsgraph, ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MLOOPUV | CD_MASK_MTFACE); ps->dm_release = true; } else { ps->dm = mesh_get_derived_final( - ps->scene, ps->ob, + depsgraph, ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MLOOPUV | CD_MASK_MTFACE | (ps->do_face_sel ? CD_MASK_ORIGINDEX : 0)); ps->dm_release = false; } - - if (!CustomData_has_layer(&ps->dm->loopData, CD_MLOOPUV)) { - - if (ps->dm_release) - ps->dm->release(ps->dm); - - ps->dm = NULL; +#endif + ps->me_eval = mesh_get_eval_final( + depsgraph, sce, ob, + sce->customdata_mask | CD_MASK_MLOOPUV | CD_MASK_MTFACE | (ps->do_face_sel ? CD_MASK_ORIGINDEX : 0)); + if (!CustomData_has_layer(&ps->me_eval->ldata, CD_MLOOPUV)) { + ps->me_eval = NULL; return false; } - DM_update_materials(ps->dm, ps->ob); - - ps->dm_mvert = ps->dm->getVertArray(ps->dm); - - if (ps->do_mask_cavity) - ps->dm_medge = ps->dm->getEdgeArray(ps->dm); + /* Build final material array, we use this a lot here. */ + const int totmat = ob->totcol + 1; /* materials start from 1, default material is 0 */ + ps->mat_array = MEM_malloc_arrayN(totmat, sizeof(*ps->mat_array), __func__); + /* We leave last material as empty - rationale here is being able to index + * the materials by using the mf->mat_nr directly and leaving the last + * material as NULL in case no materials exist on mesh, so indexing will not fail. */ + for (int i = 0; i < totmat - 1; i++) { + ps->mat_array[i] = give_current_material(ob, i + 1); + } + ps->mat_array[totmat - 1] = NULL; - ps->dm_mloop = ps->dm->getLoopArray(ps->dm); - ps->dm_mpoly = ps->dm->getPolyArray(ps->dm); + ps->mvert_eval = ps->me_eval->mvert; + if (ps->do_mask_cavity) { + ps->medge_eval = ps->me_eval->medge; + } + ps->mloop_eval = ps->me_eval->mloop; + ps->mpoly_eval = ps->me_eval->mpoly; - ps->dm_mlooptri = ps->dm->getLoopTriArray(ps->dm); + ps->totvert_eval = ps->me_eval->totvert; + ps->totedge_eval = ps->me_eval->totedge; + ps->totpoly_eval = ps->me_eval->totpoly; - ps->dm_totvert = ps->dm->getNumVerts(ps->dm); - ps->dm_totedge = ps->dm->getNumEdges(ps->dm); - ps->dm_totpoly = ps->dm->getNumPolys(ps->dm); - ps->dm_totlooptri = ps->dm->getNumLoopTri(ps->dm); + ps->mlooptri_eval = BKE_mesh_runtime_looptri_ensure(ps->me_eval); + ps->totlooptri_eval = ps->me_eval->runtime.looptris.len; - ps->dm_mloopuv = MEM_mallocN(ps->dm_totpoly * sizeof(MLoopUV *), "proj_paint_mtfaces"); + ps->poly_to_loop_uv = MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces"); return true; } @@ -3483,16 +3467,16 @@ static void proj_paint_layer_clone_init( /* use clone mtface? */ if (ps->do_layer_clone) { - const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY); + const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV); - ps->dm_mloopuv_clone = MEM_mallocN(ps->dm_totpoly * sizeof(MLoopUV *), "proj_paint_mtfaces"); + ps->poly_to_loop_uv_clone = MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces"); if (layer_num != -1) - mloopuv_clone_base = CustomData_get_layer_n(&ps->dm->loopData, CD_MLOOPUV, layer_num); + mloopuv_clone_base = CustomData_get_layer_n(&ps->me_eval->ldata, CD_MLOOPUV, layer_num); if (mloopuv_clone_base == NULL) { /* get active instead */ - mloopuv_clone_base = CustomData_get_layer(&ps->dm->loopData, CD_MLOOPUV); + mloopuv_clone_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV); } } @@ -3522,17 +3506,17 @@ static bool project_paint_clone_face_skip( if (lc->slot_clone != lc->slot_last_clone) { if (!slot->uvname || !(lc->mloopuv_clone_base = CustomData_get_layer_named( - &ps->dm->loopData, CD_MLOOPUV, + &ps->me_eval->ldata, CD_MLOOPUV, lc->slot_clone->uvname))) { - lc->mloopuv_clone_base = CustomData_get_layer(&ps->dm->loopData, CD_MLOOPUV); + lc->mloopuv_clone_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV); } lc->slot_last_clone = lc->slot_clone; } } /* will set multiple times for 4+ sided poly */ - ps->dm_mloopuv_clone[ps->dm_mlooptri[tri_index].poly] = lc->mloopuv_clone_base; + ps->poly_to_loop_uv_clone[ps->mlooptri_eval[tri_index].poly] = lc->mloopuv_clone_base; } return false; } @@ -3549,7 +3533,7 @@ static void proj_paint_face_lookup_init( { memset(face_lookup, 0, sizeof(*face_lookup)); if (ps->do_face_sel) { - face_lookup->index_mp_to_orig = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX); + face_lookup->index_mp_to_orig = CustomData_get_layer(&ps->me_eval->pdata, CD_ORIGINDEX); face_lookup->mpoly_orig = ((Mesh *)ps->ob->data)->mpoly; } } @@ -3570,7 +3554,7 @@ static bool project_paint_check_face_sel( mp = &face_lookup->mpoly_orig[orig_index]; } else { - mp = &ps->dm_mpoly[lt->poly]; + mp = &ps->mpoly_eval[lt->poly]; } return ((mp->flag & ME_FACE_SEL) != 0); @@ -3684,7 +3668,7 @@ static void project_paint_prepare_all_faces( int image_index = -1, tri_index; int prev_poly = -1; - for (tri_index = 0, lt = ps->dm_mlooptri; tri_index < ps->dm_totlooptri; tri_index++, lt++) { + for (tri_index = 0, lt = ps->mlooptri_eval; tri_index < ps->totlooptri_eval; tri_index++, lt++) { bool is_face_sel; #ifndef PROJ_DEBUG_NOSEAMBLEED @@ -3697,13 +3681,13 @@ static void project_paint_prepare_all_faces( slot = project_paint_face_paint_slot(ps, tri_index); /* all faces should have a valid slot, reassert here */ if (slot == NULL) { - mloopuv_base = CustomData_get_layer(&ps->dm->loopData, CD_MLOOPUV); + mloopuv_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV); tpage = ps->canvas_ima; } else { if (slot != slot_last) { - if (!slot->uvname || !(mloopuv_base = CustomData_get_layer_named(&ps->dm->loopData, CD_MLOOPUV, slot->uvname))) - mloopuv_base = CustomData_get_layer(&ps->dm->loopData, CD_MLOOPUV); + if (!slot->uvname || !(mloopuv_base = CustomData_get_layer_named(&ps->me_eval->ldata, CD_MLOOPUV, slot->uvname))) + mloopuv_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV); slot_last = slot; } @@ -3711,7 +3695,7 @@ static void project_paint_prepare_all_faces( if (slot->ima == ps->stencil_ima) { /* While this shouldn't be used, face-winding reads all polys. * It's less trouble to set all faces to valid UV's, avoiding NULL checks all over. */ - ps->dm_mloopuv[lt->poly] = mloopuv_base; + ps->poly_to_loop_uv[lt->poly] = mloopuv_base; continue; } @@ -3722,7 +3706,7 @@ static void project_paint_prepare_all_faces( tpage = ps->stencil_ima; } - ps->dm_mloopuv[lt->poly] = mloopuv_base; + ps->poly_to_loop_uv[lt->poly] = mloopuv_base; if (project_paint_clone_face_skip(ps, layer_clone, slot, tri_index)) { continue; @@ -3753,11 +3737,11 @@ static void project_paint_prepare_all_faces( if (prev_poly != lt->poly) { int iloop; bool culled = true; - const MPoly *poly = ps->dm_mpoly + lt->poly; + const MPoly *poly = ps->mpoly_eval + lt->poly; int poly_loops = poly->totloop; prev_poly = lt->poly; for (iloop = 0; iloop < poly_loops; iloop++) { - if (!(ps->vertFlags[ps->dm_mloop[poly->loopstart + iloop].v] & PROJ_VERT_CULL)) { + if (!(ps->vertFlags[ps->mloop_eval[poly->loopstart + iloop].v] & PROJ_VERT_CULL)) { culled = false; break; } @@ -3813,7 +3797,7 @@ static void project_paint_prepare_all_faces( /* run once per stroke before projection painting */ static void project_paint_begin( - ProjPaintState *ps, + const bContext *C, ProjPaintState *ps, const bool is_multi_view, const char symmetry_flag) { ProjPaintLayerClone layer_clone; @@ -3836,7 +3820,7 @@ static void project_paint_begin( /* paint onto the derived mesh */ if (ps->is_shared_user == false) { - if (!proj_paint_state_dm_init(ps)) { + if (!proj_paint_state_mesh_eval_init(C, ps)) { return; } } @@ -3845,28 +3829,26 @@ static void project_paint_begin( proj_paint_layer_clone_init(ps, &layer_clone); if (ps->do_layer_stencil || ps->do_stencil_brush) { - //int layer_num = CustomData_get_stencil_layer(&ps->dm->loopData, CD_MLOOPUV); - int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY); + //int layer_num = CustomData_get_stencil_layer(&ps->me_eval->ldata, CD_MLOOPUV); + int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV); if (layer_num != -1) - ps->dm_mloopuv_stencil = CustomData_get_layer_n(&ps->dm->loopData, CD_MLOOPUV, layer_num); + ps->mloopuv_stencil_eval = CustomData_get_layer_n(&ps->me_eval->ldata, CD_MLOOPUV, layer_num); - if (ps->dm_mloopuv_stencil == NULL) { + if (ps->mloopuv_stencil_eval == NULL) { /* get active instead */ - ps->dm_mloopuv_stencil = CustomData_get_layer(&ps->dm->loopData, CD_MLOOPUV); + ps->mloopuv_stencil_eval = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV); } if (ps->do_stencil_brush) - mloopuv_base = ps->dm_mloopuv_stencil; + mloopuv_base = ps->mloopuv_stencil_eval; } /* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */ if (ps->is_shared_user == false) { - proj_paint_state_non_cddm_init(ps); - proj_paint_state_cavity_init(ps); } - proj_paint_state_viewport_init(ps, symmetry_flag); + proj_paint_state_viewport_init(ps, CTX_data_depsgraph(C), symmetry_flag); /* calculate vert screen coords * run this early so we can calculate the x/y resolution of our bucket rect */ @@ -3913,7 +3895,7 @@ static void paint_proj_begin_clone(ProjPaintState *ps, const float mouse[2]) /* setup clone offset */ if (ps->tool == PAINT_TOOL_CLONE) { float projCo[4]; - copy_v3_v3(projCo, ED_view3d_cursor3d_get(ps->scene, ps->v3d)); + copy_v3_v3(projCo, ED_view3d_cursor3d_get(ps->scene, ps->v3d)->location); mul_m4_v3(ps->obmat_imat, projCo); projCo[3] = 1.0f; @@ -3934,7 +3916,7 @@ static void project_paint_end(ProjPaintState *ps) ProjPaintImage *projIma; for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) { BKE_image_release_ibuf(projIma->ima, projIma->ibuf, NULL); - DAG_id_tag_update(&projIma->ima->id, 0); + DEG_id_tag_update(&projIma->ima->id, 0); } } @@ -3952,14 +3934,17 @@ static void project_paint_end(ProjPaintState *ps) MEM_freeN(ps->bucketFlags); if (ps->is_shared_user == false) { + if (ps->mat_array != NULL) { + MEM_freeN(ps->mat_array); + } /* must be set for non-shared */ - BLI_assert(ps->dm_mloopuv || ps->is_shared_user); - if (ps->dm_mloopuv) - MEM_freeN((void *)ps->dm_mloopuv); + BLI_assert(ps->poly_to_loop_uv || ps->is_shared_user); + if (ps->poly_to_loop_uv) + MEM_freeN((void *)ps->poly_to_loop_uv); if (ps->do_layer_clone) - MEM_freeN((void *)ps->dm_mloopuv_clone); + MEM_freeN((void *)ps->poly_to_loop_uv_clone); if (ps->thread_tot > 1) { BLI_spin_end(ps->tile_lock); MEM_freeN((void *)ps->tile_lock); @@ -3979,22 +3964,6 @@ static void project_paint_end(ProjPaintState *ps) if (ps->do_mask_cavity) { MEM_freeN(ps->cavities); } - - /* copy for subsurf/multires, so throw away */ - if (ps->dm->type != DM_TYPE_CDDM) { - if (ps->dm_mvert) MEM_freeN((void *)ps->dm_mvert); - if (ps->dm_mpoly) MEM_freeN((void *)ps->dm_mpoly); - if (ps->dm_mloop) MEM_freeN((void *)ps->dm_mloop); - /* looks like these don't need copying */ -#if 0 - if (ps->dm_mloopuv) MEM_freeN(ps->dm_mloopuv); - if (ps->dm_mloopuv_clone) MEM_freeN(ps->dm_mloopuv_clone); - if (ps->dm_mloopuv_stencil) MEM_freeN(ps->dm_mloopuv_stencil); -#endif - } - - if (ps->dm_release) - ps->dm->release(ps->dm); } if (ps->blurkernel) { @@ -4869,7 +4838,7 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po struct ImagePool *pool; if (!project_bucket_iter_init(ps, pos)) { - return 0; + return touch_any; } if (ps->thread_tot > 1) @@ -4935,16 +4904,16 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po tri_index = project_paint_PickFace(ps, pos, w); if (tri_index != -1) { - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) }; float world[3]; UnifiedPaintSettings *ups = &ps->scene->toolsettings->unified_paint_settings; interp_v3_v3v3v3( world, - ps->dm_mvert[lt_vtri[0]].co, - ps->dm_mvert[lt_vtri[1]].co, - ps->dm_mvert[lt_vtri[2]].co, + ps->mvert_eval[lt_vtri[0]].co, + ps->mvert_eval[lt_vtri[1]].co, + ps->mvert_eval[lt_vtri[2]].co, w); ups->average_stroke_counter++; @@ -5019,17 +4988,18 @@ void paint_proj_stroke( /* clone gets special treatment here to avoid going through image initialization */ if (ps_handle->is_clone_cursor_pick) { - Main *bmain = CTX_data_main(C); Scene *scene = ps_handle->scene; + struct Depsgraph *depsgraph = CTX_data_depsgraph(C); View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); - float *cursor = ED_view3d_cursor3d_get(scene, v3d); + float *cursor = ED_view3d_cursor3d_get(scene, v3d)->location; int mval_i[2] = {(int)pos[0], (int)pos[1]}; view3d_operator_needs_opengl(C); - if (!ED_view3d_autodist(bmain, scene, ar, v3d, mval_i, cursor, false, NULL)) + if (!ED_view3d_autodist(depsgraph, ar, v3d, mval_i, cursor, false, NULL)) { return; + } ED_region_tag_redraw(ar); @@ -5085,6 +5055,7 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int ps->rv3d = CTX_wm_region_view3d(C); ps->ar = CTX_wm_region(C); + ps->depsgraph = CTX_data_depsgraph(C); ps->scene = scene; ps->ob = ob; /* allow override of active object */ @@ -5107,7 +5078,6 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int else { ps->do_backfacecull = ps->do_occlude = ps->do_mask_normal = 0; } - ps->do_new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); /* only cache the value */ if (ps->tool == PAINT_TOOL_CLONE) ps->do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) ? 1 : 0; @@ -5207,7 +5177,7 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m project_state_init(C, ob, ps, mode); - if (ps->ob == NULL || !(ps->ob->lay & ps->v3d->lay)) { + if (ps->ob == NULL) { ps_handle->ps_views_tot = i + 1; goto fail; } @@ -5231,14 +5201,12 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m PROJ_PAINT_STATE_SHARED_MEMCPY(ps, ps_handle->ps_views[0]); } - project_paint_begin(ps, is_multi_view, symmetry_flag_views[i]); - - paint_proj_begin_clone(ps, mouse); - - if (ps->dm == NULL) { + project_paint_begin(C, ps, is_multi_view, symmetry_flag_views[i]); + if (ps->me_eval == NULL) { goto fail; - return NULL; } + + paint_proj_begin_clone(ps, mouse); } paint_brush_init_tex(ps_handle->brush); @@ -5309,11 +5277,12 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) { Image *image = BLI_findlink(&CTX_data_main(C)->image, RNA_enum_get(op->ptr, "image")); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); ProjPaintState ps = {NULL}; int orig_brush_size; IDProperty *idgroup; IDProperty *view_data = NULL; - Object *ob = OBACT; + Object *ob = OBACT(view_layer); bool uvs, mat, tex; if (ob == NULL || ob->type != OB_MESH) { @@ -5383,10 +5352,11 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) ED_image_undo_push_begin(op->type->name); /* allocate and initialize spatial data structures */ - project_paint_begin(&ps, false, 0); + project_paint_begin(C, &ps, false, 0); - if (ps.dm == NULL) { + if (ps.me_eval == NULL) { BKE_brush_size_set(scene, ps.brush, orig_brush_size); + BKE_report(op->reports, RPT_ERROR, "Could not get valid evaluated mesh"); return OPERATOR_CANCELLED; } else { @@ -5441,8 +5411,11 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) char filename[FILE_MAX]; Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); ToolSettings *settings = scene->toolsettings; + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); int w = settings->imapaint.screen_grab_size[0]; int h = settings->imapaint.screen_grab_size[1]; int maxsize; @@ -5456,9 +5429,10 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (h > maxsize) h = maxsize; ibuf = ED_view3d_draw_offscreen_imbuf( - bmain, scene, CTX_wm_view3d(C), CTX_wm_region(C), + depsgraph, scene, v3d->drawtype, + v3d, CTX_wm_region(C), w, h, IB_rect, V3D_OFSDRAW_NONE, R_ALPHAPREMUL, 0, NULL, - NULL, NULL, err_out); + NULL, err_out); if (!ibuf) { /* Mostly happens when OpenGL offscreen buffer was failed to create, */ /* but could be other reasons. Should be handled in the future. nazgul */ @@ -5474,9 +5448,6 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (image) { /* now for the trickiness. store the view projection here! * re-projection will reuse this */ - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); - IDPropertyTemplate val; IDProperty *idgroup = IDP_GetProperties(&image->id, 1); IDProperty *view_data; @@ -5490,7 +5461,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) array = (float *)IDP_Array(view_data); memcpy(array, rv3d->winmat, sizeof(rv3d->winmat)); array += sizeof(rv3d->winmat) / sizeof(float); memcpy(array, rv3d->viewmat, sizeof(rv3d->viewmat)); array += sizeof(rv3d->viewmat) / sizeof(float); - is_ortho = ED_view3d_clip_range_get(v3d, rv3d, &array[0], &array[1], true); + is_ortho = ED_view3d_clip_range_get(CTX_data_depsgraph(C), v3d, rv3d, &array[0], &array[1], true); /* using float for a bool is dodgy but since its an extra member in the array... * easier then adding a single bool prop */ array[2] = is_ortho ? 1.0f : 0.0f; @@ -5590,7 +5561,7 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m } me = BKE_mesh_from_object(ob); - layernum = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); + layernum = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); if (layernum == 0) { hasuvs = false; @@ -5629,20 +5600,11 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m /* Add layer operator */ static const EnumPropertyItem layer_type_items[] = { - {MAP_COL, "DIFFUSE_COLOR", 0, "Diffuse Color", ""}, - {MAP_REF, "DIFFUSE_INTENSITY", 0, "Diffuse Intensity", ""}, - {MAP_ALPHA, "ALPHA", 0, "Alpha", ""}, - {MAP_TRANSLU, "TRANSLUCENCY", 0, "Translucency", ""}, - {MAP_COLSPEC, "SPECULAR_COLOR", 0, "Specular Color", ""}, - {MAP_SPEC, "SPECULAR_INTENSITY", 0, "Specular Intensity", ""}, - {MAP_HAR, "SPECULAR_HARDNESS", 0, "Specular Hardness", ""}, - {MAP_AMB, "AMBIENT", 0, "Ambient", ""}, - {MAP_EMIT, "EMIT", 0, "Emit", ""}, - {MAP_COLMIR, "MIRROR_COLOR", 0, "Mirror Color", ""}, - {MAP_RAYMIRR, "RAYMIRROR", 0, "Ray Mirror", ""}, - {MAP_NORM, "NORMAL", 0, "Normal", ""}, - {MAP_WARP, "WARP", 0, "Warp", ""}, - {MAP_DISPLACE, "DISPLACE", 0, "Displace", ""}, + {0, "BASE_COLOR", 0, "Base Color", ""}, + {1, "EMISSION", 0, "Emission", ""}, + {2, "NORMAL", 0, "Normal", ""}, + {3, "BUMP", 0, "Bump", ""}, + {4, "DISPLACEMENT", 0, "Displacement", ""}, {0, NULL, 0, NULL, NULL} }; @@ -5677,7 +5639,6 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op) Object *ob = ED_object_active_context(C); Scene *scene = CTX_data_scene(C); Material *ma; - bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene); Image *ima = NULL; if (!ob) @@ -5686,60 +5647,34 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op) ma = give_current_material(ob, ob->actcol); if (ma) { + /* TODO: use type to link to proper socket. */ Main *bmain = CTX_data_main(C); - if (!is_bi && BKE_scene_use_new_shading_nodes(scene)) { - bNode *imanode; - bNodeTree *ntree = ma->nodetree; + bNode *imanode; + bNodeTree *ntree = ma->nodetree; - if (!ntree) { - ED_node_shader_default(C, &ma->id); - ntree = ma->nodetree; - } - - ma->use_nodes = true; + if (!ntree) { + ED_node_shader_default(C, &ma->id); + ntree = ma->nodetree; + } - /* try to add an image node */ - imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE); + ma->use_nodes = true; - ima = proj_paint_image_create(op, bmain); - imanode->id = &ima->id; + /* try to add an image node */ + imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE); - nodeSetActive(ntree, imanode); + ima = proj_paint_image_create(op, bmain); + imanode->id = &ima->id; - ntreeUpdateTree(CTX_data_main(C), ntree); - } - else { - MTex *mtex = BKE_texture_mtex_add_id(&ma->id, -1); - - /* successful creation of mtex layer, now create set */ - if (mtex) { - int type = MAP_COL; - char imagename_buff[MAX_ID_NAME - 2]; - const char *imagename = DATA_("Diffuse Color"); - - if (op) { - type = RNA_enum_get(op->ptr, "type"); - RNA_string_get(op->ptr, "name", imagename_buff); - imagename = imagename_buff; - } + nodeSetActive(ntree, imanode); - mtex->tex = BKE_texture_add(bmain, imagename); - mtex->mapto = type; - - if (mtex->tex) { - ima = mtex->tex->ima = proj_paint_image_create(op, bmain); - } - - WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, mtex->tex); - } - } + ntreeUpdateTree(CTX_data_main(C), ntree); if (ima) { BKE_texpaint_slot_refresh_cache(scene, ma); BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE); WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima); - DAG_id_tag_update(&ma->id, 0); + DEG_id_tag_update(&ma->id, 0); ED_area_tag_redraw(CTX_wm_area(C)); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); @@ -5826,59 +5761,6 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot) RNA_def_boolean(ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth"); } -static int texture_paint_delete_texture_paint_slot_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *ob = CTX_data_active_object(C); - Scene *scene = CTX_data_scene(C); - Material *ma; - bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene); - TexPaintSlot *slot; - - /* not supported for node-based engines */ - if (!ob || !is_bi) - return OPERATOR_CANCELLED; - - ma = give_current_material(ob, ob->actcol); - - if (!ma->texpaintslot || ma->use_nodes) - return OPERATOR_CANCELLED; - - slot = ma->texpaintslot + ma->paint_active_slot; - - if (ma->mtex[slot->index]->tex) { - id_us_min(&ma->mtex[slot->index]->tex->id); - - if (ma->mtex[slot->index]->tex->ima) { - id_us_min(&ma->mtex[slot->index]->tex->ima->id); - } - } - MEM_freeN(ma->mtex[slot->index]); - ma->mtex[slot->index] = NULL; - - BKE_texpaint_slot_refresh_cache(scene, ma); - DAG_id_tag_update(&ma->id, 0); - WM_event_add_notifier(C, NC_MATERIAL, ma); - /* we need a notifier for data change since we change the displayed modifier uvs */ - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); - return OPERATOR_FINISHED; -} - - -void PAINT_OT_delete_texture_paint_slot(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Delete Texture Paint Slot"; - ot->description = "Delete selected texture paint slot"; - ot->idname = "PAINT_OT_delete_texture_paint_slot"; - - /* api callbacks */ - ot->exec = texture_paint_delete_texture_paint_slot_exec; - ot->poll = ED_operator_region_view3d_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op)) { /* no checks here, poll function does them for us */ @@ -5915,7 +5797,7 @@ static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op)) BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); - DAG_id_tag_update(ob->data, 0); + DEG_id_tag_update(ob->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, scene); return OPERATOR_FINISHED; @@ -5925,9 +5807,9 @@ static int add_simple_uvs_poll(bContext *C) { Object *ob = CTX_data_active_object(C); - if (!ob || ob->type != OB_MESH || ob->mode != OB_MODE_TEXTURE_PAINT) + if (!ob || ob->type != OB_MESH || ob->mode != OB_MODE_TEXTURE_PAINT) { return false; - + } return true; } |