Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/paint_image_proj.cc
| Show First 20 Lines • Show All 415 Lines • ▼ Show 20 Lines | #endif | ||||
| const float (*vert_normals)[3]; | const float (*vert_normals)[3]; | ||||
| const MEdge *medge_eval; | const MEdge *medge_eval; | ||||
| const MPoly *mpoly_eval; | const MPoly *mpoly_eval; | ||||
| const bool *select_poly_eval; | const bool *select_poly_eval; | ||||
| const int *material_indices; | const int *material_indices; | ||||
| const MLoop *mloop_eval; | const MLoop *mloop_eval; | ||||
| const MLoopTri *mlooptri_eval; | const MLoopTri *mlooptri_eval; | ||||
| const MLoopUV *mloopuv_stencil_eval; | const float (*mloopuv_stencil_eval)[2]; | ||||
| /** | /** | ||||
| * \note These UV layers are aligned to \a mpoly_eval | * \note These UV layers are aligned to \a mpoly_eval | ||||
| * but each pointer references the start of the layer, | * but each pointer references the start of the layer, | ||||
| * so a loop indirection is needed as well. | * so a loop indirection is needed as well. | ||||
| */ | */ | ||||
| const MLoopUV **poly_to_loop_uv; | const float (**poly_to_loop_uv)[2]; | ||||
| /** other UV map, use for cloning between layers. */ | /** other UV map, use for cloning between layers. */ | ||||
| const MLoopUV **poly_to_loop_uv_clone; | const float (**poly_to_loop_uv_clone)[2]; | ||||
| /* Actual material for each index, either from object or Mesh datablock... */ | /* Actual material for each index, either from object or Mesh datablock... */ | ||||
| Material **mat_array; | Material **mat_array; | ||||
| bool use_colormanagement; | bool use_colormanagement; | ||||
| }; | }; | ||||
| union PixelPointer { | union PixelPointer { | ||||
| ▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | BLI_INLINE const MPoly *ps_tri_index_to_mpoly(const ProjPaintState *ps, int tri_index) | ||||
| return &ps->mpoly_eval[ps->mlooptri_eval[tri_index].poly]; | return &ps->mpoly_eval[ps->mlooptri_eval[tri_index].poly]; | ||||
| } | } | ||||
| #define PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) \ | #define PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) \ | ||||
| int(ps->mloop_eval[lt->tri[0]].v), int(ps->mloop_eval[lt->tri[1]].v), \ | int(ps->mloop_eval[lt->tri[0]].v), int(ps->mloop_eval[lt->tri[1]].v), \ | ||||
| int(ps->mloop_eval[lt->tri[2]].v), | int(ps->mloop_eval[lt->tri[2]].v), | ||||
| #define PS_LOOPTRI_AS_UV_3(uvlayer, lt) \ | #define PS_LOOPTRI_AS_UV_3(uvlayer, lt) \ | ||||
| uvlayer[lt->poly][lt->tri[0]].uv, uvlayer[lt->poly][lt->tri[1]].uv, \ | uvlayer[lt->poly][lt->tri[0]], uvlayer[lt->poly][lt->tri[1]], uvlayer[lt->poly][lt->tri[2]], | ||||
| uvlayer[lt->poly][lt->tri[2]].uv, | |||||
| #define PS_LOOPTRI_ASSIGN_UV_3(uv_tri, uvlayer, lt) \ | #define PS_LOOPTRI_ASSIGN_UV_3(uv_tri, uvlayer, lt) \ | ||||
| { \ | { \ | ||||
| (uv_tri)[0] = uvlayer[lt->poly][lt->tri[0]].uv; \ | (uv_tri)[0] = uvlayer[lt->poly][lt->tri[0]]; \ | ||||
| (uv_tri)[1] = uvlayer[lt->poly][lt->tri[1]].uv; \ | (uv_tri)[1] = uvlayer[lt->poly][lt->tri[1]]; \ | ||||
| (uv_tri)[2] = uvlayer[lt->poly][lt->tri[2]].uv; \ | (uv_tri)[2] = uvlayer[lt->poly][lt->tri[2]]; \ | ||||
| } \ | } \ | ||||
| ((void)0) | ((void)0) | ||||
| /** \} */ | /** \} */ | ||||
| /* Finish projection painting structs */ | /* Finish projection painting structs */ | ||||
| static int project_paint_face_paint_tile(Image *ima, const float *uv) | static int project_paint_face_paint_tile(Image *ima, const float *uv) | ||||
| ▲ Show 20 Lines • Show All 1,130 Lines • ▼ Show 20 Lines | static float project_paint_uvpixel_mask(const ProjPaintState *ps, | ||||
| /* Image Mask */ | /* Image Mask */ | ||||
| if (ps->do_layer_stencil) { | if (ps->do_layer_stencil) { | ||||
| /* another UV maps image is masking this one's */ | /* another UV maps image is masking this one's */ | ||||
| ImBuf *ibuf_other; | ImBuf *ibuf_other; | ||||
| Image *other_tpage = ps->stencil_ima; | Image *other_tpage = ps->stencil_ima; | ||||
| if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, nullptr, nullptr))) { | if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, nullptr, nullptr))) { | ||||
| const MLoopTri *lt_other = &ps->mlooptri_eval[tri_index]; | const MLoopTri *lt_other = &ps->mlooptri_eval[tri_index]; | ||||
| const float *lt_other_tri_uv[3] = {ps->mloopuv_stencil_eval[lt_other->tri[0]].uv, | const float *lt_other_tri_uv[3] = {ps->mloopuv_stencil_eval[lt_other->tri[0]], | ||||
| ps->mloopuv_stencil_eval[lt_other->tri[1]].uv, | ps->mloopuv_stencil_eval[lt_other->tri[1]], | ||||
| ps->mloopuv_stencil_eval[lt_other->tri[2]].uv}; | ps->mloopuv_stencil_eval[lt_other->tri[2]]}; | ||||
| /* #BKE_image_acquire_ibuf - TODO: this may be slow. */ | /* #BKE_image_acquire_ibuf - TODO: this may be slow. */ | ||||
| uchar rgba_ub[4]; | uchar rgba_ub[4]; | ||||
| float rgba_f[4]; | float rgba_f[4]; | ||||
| project_face_pixel(lt_other_tri_uv, ibuf_other, w, rgba_ub, rgba_f); | project_face_pixel(lt_other_tri_uv, ibuf_other, w, rgba_ub, rgba_f); | ||||
| if (ibuf_other->rect_float) { /* from float to float */ | if (ibuf_other->rect_float) { /* from float to float */ | ||||
| ▲ Show 20 Lines • Show All 2,357 Lines • ▼ Show 20 Lines | static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *ps) | ||||
| Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); | Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); | ||||
| if (scene_eval == nullptr || ob_eval == nullptr) { | if (scene_eval == nullptr || ob_eval == nullptr) { | ||||
| 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; | ||||
| cddata_masks.lmask |= CD_MASK_MLOOPUV; | cddata_masks.lmask |= CD_MASK_PROP_FLOAT2; | ||||
| if (ps->do_face_sel) { | if (ps->do_face_sel) { | ||||
| 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); | ||||
| if (!CustomData_has_layer(&ps->me_eval->ldata, CD_MLOOPUV)) { | if (!CustomData_has_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)) { | ||||
| ps->me_eval = nullptr; | ps->me_eval = nullptr; | ||||
| 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 = static_cast<Material **>( | ps->mat_array = static_cast<Material **>( | ||||
| Show All 21 Lines | static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *ps) | ||||
| ps->totvert_eval = ps->me_eval->totvert; | ps->totvert_eval = ps->me_eval->totvert; | ||||
| ps->totedge_eval = ps->me_eval->totedge; | ps->totedge_eval = ps->me_eval->totedge; | ||||
| ps->totpoly_eval = ps->me_eval->totpoly; | ps->totpoly_eval = ps->me_eval->totpoly; | ||||
| ps->totloop_eval = ps->me_eval->totloop; | ps->totloop_eval = ps->me_eval->totloop; | ||||
| ps->mlooptri_eval = BKE_mesh_runtime_looptri_ensure(ps->me_eval); | ps->mlooptri_eval = BKE_mesh_runtime_looptri_ensure(ps->me_eval); | ||||
| ps->totlooptri_eval = BKE_mesh_runtime_looptri_len(ps->me_eval); | ps->totlooptri_eval = BKE_mesh_runtime_looptri_len(ps->me_eval); | ||||
| ps->poly_to_loop_uv = static_cast<const MLoopUV **>( | ps->poly_to_loop_uv = static_cast<const float(**)[2]>( | ||||
| MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces")); | MEM_mallocN(ps->totpoly_eval * sizeof(float(*)[2]), "proj_paint_mtfaces")); | ||||
| return true; | return true; | ||||
| } | } | ||||
| struct ProjPaintLayerClone { | struct ProjPaintLayerClone { | ||||
| const MLoopUV *mloopuv_clone_base; | const float (*mloopuv_clone_base)[2]; | ||||
| const TexPaintSlot *slot_last_clone; | const TexPaintSlot *slot_last_clone; | ||||
| const TexPaintSlot *slot_clone; | const TexPaintSlot *slot_clone; | ||||
| }; | }; | ||||
| static void proj_paint_layer_clone_init(ProjPaintState *ps, ProjPaintLayerClone *layer_clone) | static void proj_paint_layer_clone_init(ProjPaintState *ps, ProjPaintLayerClone *layer_clone) | ||||
| { | { | ||||
| const MLoopUV *mloopuv_clone_base = nullptr; | const float(*mloopuv_clone_base)[2] = nullptr; | ||||
| /* use clone mtface? */ | /* use clone mtface? */ | ||||
| if (ps->do_layer_clone) { | if (ps->do_layer_clone) { | ||||
| const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV); | const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->ldata, | ||||
| CD_PROP_FLOAT2); | |||||
| ps->poly_to_loop_uv_clone = static_cast<const MLoopUV **>( | ps->poly_to_loop_uv_clone = static_cast<const float(**)[2]>( | ||||
| MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces")); | MEM_mallocN(ps->totpoly_eval * sizeof(float(*)[2]), "proj_paint_mtfaces")); | ||||
| if (layer_num != -1) { | if (layer_num != -1) { | ||||
| mloopuv_clone_base = static_cast<const MLoopUV *>( | mloopuv_clone_base = static_cast<const float(*)[2]>( | ||||
| CustomData_get_layer_n(&ps->me_eval->ldata, CD_MLOOPUV, layer_num)); | CustomData_get_layer_n(&ps->me_eval->ldata, CD_PROP_FLOAT2, layer_num)); | ||||
| } | } | ||||
| if (mloopuv_clone_base == nullptr) { | if (mloopuv_clone_base == nullptr) { | ||||
| /* get active instead */ | /* get active instead */ | ||||
| mloopuv_clone_base = static_cast<const MLoopUV *>( | mloopuv_clone_base = static_cast<const float(*)[2]>( | ||||
| CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV)); | CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)); | ||||
| } | } | ||||
| } | } | ||||
| memset(layer_clone, 0, sizeof(*layer_clone)); | memset(layer_clone, 0, sizeof(*layer_clone)); | ||||
| layer_clone->mloopuv_clone_base = mloopuv_clone_base; | layer_clone->mloopuv_clone_base = mloopuv_clone_base; | ||||
| } | } | ||||
| /* Return true if face should be skipped, false otherwise */ | /* Return true if face should be skipped, false otherwise */ | ||||
| Show All 12 Lines | if (ps->do_layer_clone) { | ||||
| } | } | ||||
| else if (ps->clone_ima == ps->canvas_ima) { | else if (ps->clone_ima == ps->canvas_ima) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (ps->do_material_slots) { | if (ps->do_material_slots) { | ||||
| if (lc->slot_clone != lc->slot_last_clone) { | if (lc->slot_clone != lc->slot_last_clone) { | ||||
| if (!lc->slot_clone->uvname || | if (!lc->slot_clone->uvname || | ||||
| !(lc->mloopuv_clone_base = static_cast<const MLoopUV *>(CustomData_get_layer_named( | !(lc->mloopuv_clone_base = static_cast<const float(*)[2]>(CustomData_get_layer_named( | ||||
| &ps->me_eval->ldata, CD_MLOOPUV, lc->slot_clone->uvname)))) { | &ps->me_eval->ldata, CD_PROP_FLOAT2, lc->slot_clone->uvname)))) { | ||||
| lc->mloopuv_clone_base = static_cast<const MLoopUV *>( | lc->mloopuv_clone_base = static_cast<const float(*)[2]>( | ||||
| CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV)); | CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)); | ||||
| } | } | ||||
| lc->slot_last_clone = lc->slot_clone; | lc->slot_last_clone = lc->slot_clone; | ||||
| } | } | ||||
| } | } | ||||
| /* will set multiple times for 4+ sided poly */ | /* will set multiple times for 4+ sided poly */ | ||||
| ps->poly_to_loop_uv_clone[ps->mlooptri_eval[tri_index].poly] = lc->mloopuv_clone_base; | ps->poly_to_loop_uv_clone[ps->mlooptri_eval[tri_index].poly] = lc->mloopuv_clone_base; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | for (entry = static_cast<PrepareImageEntry *>(used_images->first), i = 0; entry; | ||||
| memset(projIma->valid, 0, size); | memset(projIma->valid, 0, size); | ||||
| } | } | ||||
| } | } | ||||
| static void project_paint_prepare_all_faces(ProjPaintState *ps, | static void project_paint_prepare_all_faces(ProjPaintState *ps, | ||||
| MemArena *arena, | MemArena *arena, | ||||
| const ProjPaintFaceLookup *face_lookup, | const ProjPaintFaceLookup *face_lookup, | ||||
| ProjPaintLayerClone *layer_clone, | ProjPaintLayerClone *layer_clone, | ||||
| const MLoopUV *mloopuv_base, | const float (*mloopuv_base)[2], | ||||
| const bool is_multi_view) | const bool is_multi_view) | ||||
| { | { | ||||
| /* Image Vars - keep track of images we have used */ | /* Image Vars - keep track of images we have used */ | ||||
| ListBase used_images = {nullptr}; | ListBase used_images = {nullptr}; | ||||
| Image *tpage_last = nullptr, *tpage; | Image *tpage_last = nullptr, *tpage; | ||||
| TexPaintSlot *slot_last = nullptr; | TexPaintSlot *slot_last = nullptr; | ||||
| TexPaintSlot *slot = nullptr; | TexPaintSlot *slot = nullptr; | ||||
| Show All 9 Lines | for (tri_index = 0, lt = ps->mlooptri_eval; tri_index < ps->totlooptri_eval; tri_index++, lt++) { | ||||
| bool skip_tri = false; | bool skip_tri = false; | ||||
| is_face_sel = project_paint_check_face_sel(ps, face_lookup, lt); | is_face_sel = project_paint_check_face_sel(ps, face_lookup, lt); | ||||
| if (!ps->do_stencil_brush) { | if (!ps->do_stencil_brush) { | ||||
| slot = project_paint_face_paint_slot(ps, tri_index); | slot = project_paint_face_paint_slot(ps, tri_index); | ||||
| /* all faces should have a valid slot, reassert here */ | /* all faces should have a valid slot, reassert here */ | ||||
| if (slot == nullptr) { | if (slot == nullptr) { | ||||
| mloopuv_base = static_cast<const MLoopUV *>( | mloopuv_base = static_cast<const float(*)[2]>( | ||||
| CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV)); | CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)); | ||||
| tpage = ps->canvas_ima; | tpage = ps->canvas_ima; | ||||
| } | } | ||||
| else { | else { | ||||
| if (slot != slot_last) { | if (slot != slot_last) { | ||||
| if (!slot->uvname || | if (!slot->uvname || | ||||
| !(mloopuv_base = static_cast<const MLoopUV *>( | !(mloopuv_base = static_cast<const float(*)[2]>(CustomData_get_layer_named( | ||||
| CustomData_get_layer_named(&ps->me_eval->ldata, CD_MLOOPUV, slot->uvname)))) { | &ps->me_eval->ldata, CD_PROP_FLOAT2, slot->uvname)))) { | ||||
| mloopuv_base = static_cast<const MLoopUV *>( | mloopuv_base = static_cast<const float(*)[2]>( | ||||
| CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV)); | CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)); | ||||
| } | } | ||||
| slot_last = slot; | slot_last = slot; | ||||
| } | } | ||||
| /* Don't allow using the same image for painting and stenciling. */ | /* Don't allow using the same image for painting and stenciling. */ | ||||
| if (slot->ima == ps->stencil_ima) { | if (slot->ima == ps->stencil_ima) { | ||||
| /* Delay continuing the loop until after loop_uvs and bleed faces are initialized. | /* Delay continuing the loop until after loop_uvs and bleed faces are initialized. | ||||
| * While this shouldn't be used, face-winding reads all polys. | * While this shouldn't be used, face-winding reads all polys. | ||||
| * It's less trouble to set all faces to valid UV's, | * It's less trouble to set all faces to valid UV's, | ||||
| * avoiding nullptr checks all over. */ | * avoiding nullptr checks all over. */ | ||||
| skip_tri = true; | skip_tri = true; | ||||
| tpage = nullptr; | tpage = nullptr; | ||||
| } | } | ||||
| else { | else { | ||||
| tpage = slot->ima; | tpage = slot->ima; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| tpage = ps->stencil_ima; | tpage = ps->stencil_ima; | ||||
| } | } | ||||
| ps->poly_to_loop_uv[lt->poly] = mloopuv_base; | ps->poly_to_loop_uv[lt->poly] = mloopuv_base; | ||||
| tile = project_paint_face_paint_tile(tpage, mloopuv_base[lt->tri[0]].uv); | tile = project_paint_face_paint_tile(tpage, mloopuv_base[lt->tri[0]]); | ||||
| #ifndef PROJ_DEBUG_NOSEAMBLEED | #ifndef PROJ_DEBUG_NOSEAMBLEED | ||||
| project_paint_bleed_add_face_user(ps, arena, lt, tri_index); | project_paint_bleed_add_face_user(ps, arena, lt, tri_index); | ||||
| #endif | #endif | ||||
| if (skip_tri || project_paint_clone_face_skip(ps, layer_clone, slot, tri_index)) { | if (skip_tri || project_paint_clone_face_skip(ps, layer_clone, slot, tri_index)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | |||||
| /* run once per stroke before projection painting */ | /* run once per stroke before projection painting */ | ||||
| static void project_paint_begin(const bContext *C, | static void project_paint_begin(const bContext *C, | ||||
| ProjPaintState *ps, | ProjPaintState *ps, | ||||
| const bool is_multi_view, | const bool is_multi_view, | ||||
| const char symmetry_flag) | const char symmetry_flag) | ||||
| { | { | ||||
| ProjPaintLayerClone layer_clone; | ProjPaintLayerClone layer_clone; | ||||
| ProjPaintFaceLookup face_lookup; | ProjPaintFaceLookup face_lookup; | ||||
| const MLoopUV *mloopuv_base = nullptr; | const float(*mloopuv_base)[2] = nullptr; | ||||
| /* At the moment this is just ps->arena_mt[0], but use this to show were not multi-threading. */ | /* At the moment this is just ps->arena_mt[0], but use this to show were not multi-threading. */ | ||||
| MemArena *arena; | MemArena *arena; | ||||
| const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush); | const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush); | ||||
| bool reset_threads = false; | bool reset_threads = false; | ||||
| Show All 13 Lines | if (!proj_paint_state_mesh_eval_init(C, ps)) { | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| proj_paint_face_lookup_init(ps, &face_lookup); | proj_paint_face_lookup_init(ps, &face_lookup); | ||||
| proj_paint_layer_clone_init(ps, &layer_clone); | proj_paint_layer_clone_init(ps, &layer_clone); | ||||
| if (ps->do_layer_stencil || ps->do_stencil_brush) { | if (ps->do_layer_stencil || ps->do_stencil_brush) { | ||||
| // int layer_num = CustomData_get_stencil_layer(&ps->me_eval->ldata, CD_MLOOPUV); | // int layer_num = CustomData_get_stencil_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2); | ||||
| int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV); | int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->ldata, CD_PROP_FLOAT2); | ||||
| if (layer_num != -1) { | if (layer_num != -1) { | ||||
| ps->mloopuv_stencil_eval = static_cast<const MLoopUV *>( | ps->mloopuv_stencil_eval = static_cast<const float(*)[2]>( | ||||
| CustomData_get_layer_n(&ps->me_eval->ldata, CD_MLOOPUV, layer_num)); | CustomData_get_layer_n(&ps->me_eval->ldata, CD_PROP_FLOAT2, layer_num)); | ||||
| } | } | ||||
| if (ps->mloopuv_stencil_eval == nullptr) { | if (ps->mloopuv_stencil_eval == nullptr) { | ||||
| /* get active instead */ | /* get active instead */ | ||||
| ps->mloopuv_stencil_eval = static_cast<const MLoopUV *>( | ps->mloopuv_stencil_eval = static_cast<const float(*)[2]>( | ||||
| CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV)); | CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)); | ||||
| } | } | ||||
| if (ps->do_stencil_brush) { | if (ps->do_stencil_brush) { | ||||
| mloopuv_base = ps->mloopuv_stencil_eval; | mloopuv_base = ps->mloopuv_stencil_eval; | ||||
| } | } | ||||
| } | } | ||||
| /* when using sub-surface or multi-resolution, | /* when using sub-surface or multi-resolution, | ||||
| ▲ Show 20 Lines • Show All 1,889 Lines • ▼ Show 20 Lines | bool ED_paint_proj_mesh_data_check( | ||||
| } | } | ||||
| else if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) { | else if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) { | ||||
| if (imapaint->canvas == nullptr || ID_IS_LINKED(imapaint->canvas)) { | if (imapaint->canvas == nullptr || ID_IS_LINKED(imapaint->canvas)) { | ||||
| hastex = false; | hastex = false; | ||||
| } | } | ||||
| } | } | ||||
| me = BKE_mesh_from_object(ob); | me = BKE_mesh_from_object(ob); | ||||
| layernum = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); | layernum = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); | ||||
| if (layernum == 0) { | if (layernum == 0) { | ||||
| hasuvs = false; | hasuvs = false; | ||||
| } | } | ||||
| /* Make sure we have a stencil to paint on! */ | /* Make sure we have a stencil to paint on! */ | ||||
| if (br && br->imagepaint_tool == PAINT_TOOL_MASK) { | if (br && br->imagepaint_tool == PAINT_TOOL_MASK) { | ||||
| imapaint->flag |= IMAGEPAINT_PROJECT_LAYER_STENCIL; | imapaint->flag |= IMAGEPAINT_PROJECT_LAYER_STENCIL; | ||||
| ▲ Show 20 Lines • Show All 565 Lines • Show Last 20 Lines | |||||