diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_paint.h | 36 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_pbvh.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 35 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 14 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh_intern.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 20 |
10 files changed, 112 insertions, 24 deletions
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index f7e6ab59d20..88693600653 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -160,6 +160,14 @@ void paint_update_brush_rake_rotation(struct UnifiedPaintSettings *ups, struct B void BKE_paint_stroke_get_average(struct Scene *scene, struct Object *ob, float stroke[3]); +/* Used for both vertex color and weight paint */ +struct SculptVertexPaintGeomMap { + int *vert_map_mem; + struct MeshElemMap *vert_to_loop; + int *poly_map_mem; + struct MeshElemMap *vert_to_poly; +}; + /* Session data (mode-specific) */ typedef struct SculptSession { @@ -205,10 +213,38 @@ typedef struct SculptSession { struct SculptStroke *stroke; struct StrokeCache *cache; + + union { + struct { + struct SculptVertexPaintGeomMap gmap; + + /* For non-airbrush painting to re-apply from the original (MLoop aligned). */ + unsigned int *previous_color; + } vpaint; + + struct { + struct SculptVertexPaintGeomMap gmap; + + /* Vertex aligned arrays of weights. */ + /* For non-airbrush painting to re-apply from the original. */ + float *previous_weight; + /* Keep track of how much each vertex has been painted (non-airbrush only). */ + float *alpha_weight; + } wpaint; + + //struct { + //ToDo: identify sculpt-only fields + //} sculpt; + } mode; + int mode_type; + + /* This flag prevents PBVH from being freed when creating the vp_handle for texture paint. */ + bool building_vp_handle; } SculptSession; void BKE_sculptsession_free(struct Object *ob); void BKE_sculptsession_free_deformMats(struct SculptSession *ss); +void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss); void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder); void BKE_sculptsession_bm_to_me_for_render(struct Object *object); void BKE_sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob, diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 927303f8b3c..cc84be6e2c1 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -32,6 +32,7 @@ struct CCGElem; struct CCGKey; +struct CCGDerivedMesh; struct CustomData; struct DMFlagMat; struct MPoly; @@ -71,7 +72,7 @@ void BKE_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems, struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats, unsigned int **grid_hidden); void BKE_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, bool smooth_shading, struct BMLog *log, const int cd_vert_node_offset, const int cd_face_node_offset); - +void BKE_pbvh_set_ccgdm(PBVH *bvh, struct CCGDerivedMesh *ccgdm); void BKE_pbvh_free(PBVH *bvh); void BKE_pbvh_free_layer_disp(PBVH *bvh); @@ -118,6 +119,7 @@ void BKE_pbvh_raycast_project_ray_root( void BKE_pbvh_node_draw(PBVHNode *node, void *data); void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3], int (*setMaterial)(int matnr, void *attribs), bool wireframe, bool fast); +void BKE_pbvh_draw_BB(PBVH *bvh); /* PBVH Access */ typedef enum { @@ -141,6 +143,7 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden, /* multires level, only valid for type == PBVH_GRIDS */ void BKE_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key); +struct CCGDerivedMesh *BKE_pbvh_get_ccgdm(const PBVH *bvh); /* Only valid for type == PBVH_BMESH */ struct BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index ace79f4125b..9dae4c5eae7 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2663,7 +2663,7 @@ static void mesh_build_data( ob->lastDataMask = dataMask; ob->lastNeedMapping = need_mapping; - if ((ob->mode & OB_MODE_SCULPT) && ob->sculpt) { + if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) { /* create PBVH immediately (would be created on the fly too, * but this avoids waiting on first stroke) */ diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 2c61cf28691..e97de07752e 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -662,6 +662,11 @@ static void cdDM_drawMappedFaces( const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if (cddm->pbvh) { + if (G.debug_value == 14) + BKE_pbvh_draw_BB(cddm->pbvh); + } + /* fist, setup common buffers */ GPU_vertex_setup(dm); GPU_triangle_setup(dm); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index d76ef613023..44058c989ff 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2682,7 +2682,7 @@ void BKE_object_sculpt_modifiers_changed(Object *ob) { SculptSession *ss = ob->sculpt; - if (ss) { + if (ss && ss->building_vp_handle == false) { if (!ss->cache) { /* we free pbvh on changes, except during sculpt since it can't deal with * changing PVBH node organization, we hope topology does not change in @@ -2693,6 +2693,9 @@ void BKE_object_sculpt_modifiers_changed(Object *ob) } BKE_sculptsession_free_deformMats(ob->sculpt); + + /* In vertex/weight paint, force maps to be rebuilt. */ + BKE_sculptsession_free_vwpaint_data(ob->sculpt); } else { PBVHNode **nodes; diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 9fc2136df86..25ea6ad079f 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -673,6 +673,29 @@ void BKE_sculptsession_free_deformMats(SculptSession *ss) MEM_SAFE_FREE(ss->deform_imats); } +void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss) +{ + struct SculptVertexPaintGeomMap *gmap = NULL; + if (ss->mode_type == OB_MODE_VERTEX_PAINT) { + gmap = &ss->mode.vpaint.gmap; + + MEM_SAFE_FREE(ss->mode.vpaint.previous_color); + } + else if (ss->mode_type == OB_MODE_WEIGHT_PAINT) { + gmap = &ss->mode.wpaint.gmap; + + MEM_SAFE_FREE(ss->mode.wpaint.alpha_weight); + MEM_SAFE_FREE(ss->mode.wpaint.previous_weight); + } + else { + return; + } + MEM_SAFE_FREE(gmap->vert_to_loop); + MEM_SAFE_FREE(gmap->vert_map_mem); + MEM_SAFE_FREE(gmap->vert_to_poly); + MEM_SAFE_FREE(gmap->poly_map_mem); +} + /* Write out the sculpt dynamic-topology BMesh to the Mesh */ static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder) { @@ -714,10 +737,7 @@ void BKE_sculptsession_bm_to_me_for_render(Object *object) */ BKE_object_free_derived_caches(object); - if (object->sculpt->pbvh) { - BKE_pbvh_free(object->sculpt->pbvh); - object->sculpt->pbvh = NULL; - } + MEM_SAFE_FREE(object->sculpt->pbvh); sculptsession_bm_to_me_update_data_only(object, false); @@ -764,6 +784,8 @@ void BKE_sculptsession_free(Object *ob) if (ss->deform_imats) MEM_freeN(ss->deform_imats); + BKE_sculptsession_free_vwpaint_data(ob->sculpt); + MEM_freeN(ss); ob->sculpt = NULL; @@ -848,6 +870,8 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, ss->modifiers_active = sculpt_modifiers_active(scene, sd, ob); ss->show_diffuse_color = (sd->flags & SCULPT_SHOW_DIFFUSE) != 0; + ss->building_vp_handle = false; + if (need_mask) { if (mmd == NULL) { if (!CustomData_has_layer(&me->vdata, CD_PAINT_MASK)) { @@ -876,7 +900,8 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); - if (mmd) { + /* VWPaint require mesh info for loop lookup, so require sculpt mode here */ + if (mmd && ob->mode & OB_MODE_SCULPT) { ss->multires = mmd; ss->totvert = dm->getNumVerts(dm); ss->totpoly = dm->getNumPolys(dm); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 53dfffe2b97..4b154d3301c 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -34,6 +34,7 @@ #include "BKE_pbvh.h" #include "BKE_ccg.h" +#include "BKE_subsurf.h" #include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_mesh.h" /* for BKE_mesh_calc_normals */ @@ -606,6 +607,10 @@ void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids, MEM_freeN(prim_bbc); } +void BKE_pbvh_set_ccgdm(PBVH *bvh, CCGDerivedMesh *ccgdm) { + bvh->ccgdm = ccgdm; +} + PBVH *BKE_pbvh_new(void) { PBVH *bvh = MEM_callocN(sizeof(PBVH), "pbvh"); @@ -1156,7 +1161,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode) } } -static void pbvh_draw_BB(PBVH *bvh) +void BKE_pbvh_draw_BB(PBVH *bvh) { GPU_pbvh_BB_draw_init(); @@ -1329,6 +1334,11 @@ void BKE_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key) *key = bvh->gridkey; } +CCGDerivedMesh *BKE_pbvh_get_ccgdm(const PBVH *bvh) { + return bvh->ccgdm; +} + + BMesh *BKE_pbvh_get_bmesh(PBVH *bvh) { BLI_assert(bvh->type == PBVH_BMESH); @@ -1860,7 +1870,7 @@ void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*fnors)[3], } if (G.debug_value == 14) - pbvh_draw_BB(bvh); + BKE_pbvh_draw_BB(bvh); } void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, void **gridfaces, diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index 19d3b31bd31..01057318568 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -149,6 +149,8 @@ struct PBVH { * objects in sculpt mode with different sizes at the same time, so now storing that common gpu buffer * in an opaque pointer per pbvh. See T47637. */ struct GridCommonGPUBuffer *grid_common_gpu_buffer; + /* The ccgdm is required for CD_ORIGINDEX lookup in vertex paint + multires */ + struct CCGDerivedMesh *ccgdm; /* Only used during BVH build and update, * don't need to remain valid after */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 5b809386267..c0dcac33656 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -217,16 +217,10 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons ToolSettings *ts = sce_dst->toolsettings = MEM_dupallocN(sce_dst->toolsettings); if (ts->vpaint) { ts->vpaint = MEM_dupallocN(ts->vpaint); - ts->vpaint->paintcursor = NULL; - ts->vpaint->vpaint_prev = NULL; - ts->vpaint->wpaint_prev = NULL; BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, flag_subdata); } if (ts->wpaint) { ts->wpaint = MEM_dupallocN(ts->wpaint); - ts->wpaint->paintcursor = NULL; - ts->wpaint->vpaint_prev = NULL; - ts->wpaint->wpaint_prev = NULL; BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, flag_subdata); } if (ts->sculpt) { @@ -335,16 +329,10 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type) if (ts) { if (ts->vpaint) { ts->vpaint = MEM_dupallocN(ts->vpaint); - ts->vpaint->paintcursor = NULL; - ts->vpaint->vpaint_prev = NULL; - ts->vpaint->wpaint_prev = NULL; BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, 0); } if (ts->wpaint) { ts->wpaint = MEM_dupallocN(ts->wpaint); - ts->wpaint->paintcursor = NULL; - ts->wpaint->vpaint_prev = NULL; - ts->wpaint->wpaint_prev = NULL; BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, 0); } if (ts->sculpt) { diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index f4ff4dfa019..7c5ee42b7bc 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -3683,6 +3683,11 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, int gridFaces = gridSize - 1, totface; int prev_mat_nr = -1; + if (ccgdm->pbvh) { + if (G.debug_value == 14) + BKE_pbvh_draw_BB(ccgdm->pbvh); + } + #ifdef WITH_OPENSUBDIV if (ccgdm->useGpuBackend) { int new_matnr; @@ -4416,7 +4421,8 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) if (!ob->sculpt) return NULL; - grid_pbvh = ccgDM_use_grid_pbvh(ccgdm); + /* In vwpaint, we always use a grid_pbvh for multires/subsurf */ + grid_pbvh = (!(ob->mode & OB_MODE_SCULPT) || ccgDM_use_grid_pbvh(ccgdm)); if (ob->sculpt->pbvh) { if (grid_pbvh) { @@ -4432,12 +4438,18 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) ccgdm->pbvh = ob->sculpt->pbvh; } - if (ccgdm->pbvh) + if (ccgdm->pbvh) { + /* For vertex paint, keep track of ccgdm */ + if (!(ob->mode & OB_MODE_SCULPT)) { + BKE_pbvh_set_ccgdm(ccgdm->pbvh, ccgdm); + } return ccgdm->pbvh; + } /* no pbvh exists yet, we need to create one. only in case of multires * we build a pbvh over the modified mesh, in other cases the base mesh * is being sculpted, so we build a pbvh from that. */ + /* Note: vwpaint always builds a pbvh over the modified mesh. */ if (grid_pbvh) { ccgdm_create_grids(dm); @@ -4468,6 +4480,10 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) if (ccgdm->pbvh) pbvh_show_diffuse_color_set(ccgdm->pbvh, ob->sculpt->show_diffuse_color); + /* For vertex paint, keep track of ccgdm */ + if (!(ob->mode & OB_MODE_SCULPT) && ccgdm->pbvh) { + BKE_pbvh_set_ccgdm(ccgdm->pbvh, ccgdm); + } return ccgdm->pbvh; } |