From 09b1c681e16575ee82bcc3949728189cb968d927 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 22 Mar 2010 11:59:36 +0000 Subject: [PATCH] Sculpt Mode Bugfixes: * #20833: layer brush doesn't work with multires. * #20946: sculpt mode partially removes parts of the mesh in the viewport. * #20420: grab brush stops after moving some distance. * #20906: sculpt grab tool moves in wrong direction. * #21132 and #21272: undo on object with subdivision surface modifier crashes. * #21115: subsurf + multires + sculpting + undo causes crash. * #20683: sculpt + multires apply + undo crash. * #19094: wrong outline in solid mode. --- release/scripts/ui/space_view3d_toolbar.py | 13 +- source/blender/blenkernel/BKE_DerivedMesh.h | 2 +- source/blender/blenkernel/BKE_paint.h | 7 +- source/blender/blenkernel/BKE_subsurf.h | 18 +- .../blender/blenkernel/intern/DerivedMesh.c | 14 +- .../blender/blenkernel/intern/cdderivedmesh.c | 20 ++- source/blender/blenkernel/intern/modifier.c | 5 +- source/blender/blenkernel/intern/multires.c | 18 +- source/blender/blenkernel/intern/object.c | 22 ++- .../blender/blenkernel/intern/subsurf_ccg.c | 39 +++- source/blender/editors/screen/area.c | 4 +- source/blender/editors/sculpt_paint/sculpt.c | 170 ++++++++++-------- .../blender/editors/space_view3d/drawobject.c | 22 +-- source/blender/makesdna/DNA_screen_types.h | 4 + source/blender/windowmanager/intern/wm_draw.c | 11 +- .../windowmanager/intern/wm_event_system.c | 5 +- .../blender/windowmanager/intern/wm_gesture.c | 5 +- source/blender/windowmanager/wm_draw.h | 2 + 18 files changed, 241 insertions(+), 140 deletions(-) diff --git a/release/scripts/ui/space_view3d_toolbar.py b/release/scripts/ui/space_view3d_toolbar.py index 10718883c3c..26e8ec19661 100644 --- a/release/scripts/ui/space_view3d_toolbar.py +++ b/release/scripts/ui/space_view3d_toolbar.py @@ -568,8 +568,17 @@ class VIEW3D_PT_tools_brush(PaintPanel): col.prop(brush, "use_accumulate") if brush.sculpt_tool == 'LAYER': - col.prop(brush, "use_persistent") - col.operator("sculpt.set_persistent_base") + ob = context.sculpt_object + do_persistent = True + + # not supported yet for this case + for md in ob.modifiers: + if md.type == 'MULTIRES': + do_persistent = False + + if do_persistent: + col.prop(brush, "use_persistent") + col.operator("sculpt.set_persistent_base") # Texture Paint Mode # diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index cb87638af44..965bad31991 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -227,7 +227,7 @@ struct DerivedMesh { * * Also called for *final* editmode DerivedMeshes */ - void (*drawEdges)(DerivedMesh *dm, int drawLooseEdges); + void (*drawEdges)(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges); /* Draw all loose edges (edges w/ no adjoining faces) */ void (*drawLooseEdges)(DerivedMesh *dm); diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 8fd4f079ebf..81fb724b3a5 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -69,13 +69,15 @@ typedef struct SculptSession { struct MFace *mface; int totvert, totface; float *face_normals; - struct PBVH *tree; struct Object *ob; struct KeyBlock *kb, *refkb; /* Mesh connectivity */ struct ListBase *fmap; + /* PBVH acceleration structure */ + struct PBVH *pbvh; + /* Used temporarily per-stroke */ float *vertexcosnos; @@ -87,7 +89,6 @@ typedef struct SculptSession { /* Layer brush persistence between strokes */ float (*layer_co)[3]; /* Copy of the mesh vertices' locations */ - float *layer_disps; /* Displacements for each vertex */ struct SculptStroke *stroke; struct StrokeCache *cache; @@ -95,6 +96,6 @@ typedef struct SculptSession { struct GPUDrawObject *drawobject; } SculptSession; -void free_sculptsession(SculptSession **); +void free_sculptsession(struct Object *ob); #endif diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index fca7c79d96b..853fd99aa86 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -28,19 +28,21 @@ #ifndef BKE_SUBSURF_H #define BKE_SUBSURF_H -struct Mesh; -struct Object; +struct DMGridAdjacency; +struct DMGridData; struct DerivedMesh; struct EditMesh; +struct IndexNode; +struct ListBase; +struct Mesh; struct MultiresSubsurf; +struct Object; +struct PBVH; struct SubsurfModifierData; -struct _CCGSubsurf; -struct _CCGVert; struct _CCGEdge; struct _CCGFace; -struct PBVH; -struct DMGridData; -struct DMGridAdjacency; +struct _CCGSubsurf; +struct _CCGVert; /**************************** External *****************************/ @@ -70,6 +72,8 @@ typedef struct CCGDerivedMesh { char *faceFlags; struct PBVH *pbvh; + struct ListBase *fmap; + struct IndexNode *fmap_mem; struct DMGridData **gridData; struct DMGridAdjacency *gridAdjacency; diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 6908d987a36..9d15ac3f348 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -41,10 +41,11 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" // N_T -#include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_editVert.h" +#include "BLI_math.h" #include "BLI_memarena.h" +#include "BLI_pbvh.h" #include "BKE_cdderivedmesh.h" #include "BKE_displist.h" @@ -509,7 +510,7 @@ static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us glEnd(); } } -static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) +static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges) { emDM_drawMappedEdges(dm, NULL, NULL); } @@ -2094,6 +2095,15 @@ static void clear_mesh_caches(Object *ob) ob->derivedDeform->release(ob->derivedDeform); ob->derivedDeform= NULL; } + /* 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 + the meantime .. weak */ + if(ob->sculpt && ob->sculpt->pbvh) { + if(!ob->sculpt->cache) { + BLI_pbvh_free(ob->sculpt->pbvh); + ob->sculpt->pbvh= NULL; + } + } } static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask) diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index cca554b5880..6399d55150a 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -39,12 +39,13 @@ #include "BKE_cdderivedmesh.h" #include "BKE_global.h" #include "BKE_mesh.h" +#include "BKE_paint.h" #include "BKE_utildefines.h" -#include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_editVert.h" +#include "BLI_math.h" #include "BLI_pbvh.h" #include "DNA_meshdata_types.h" @@ -188,6 +189,16 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; + if(!ob) { + cddm->pbvh= NULL; + return NULL; + } + + if(!ob->sculpt) + return NULL; + if(ob->sculpt->pbvh) + cddm->pbvh= ob->sculpt->pbvh; + if(!cddm->pbvh && ob->type == OB_MESH) { Mesh *me= ob->data; @@ -290,7 +301,7 @@ static void cdDM_drawUVEdges(DerivedMesh *dm) } } -static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) +static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; MVert *mvert = cddm->mvert; @@ -301,7 +312,7 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" ); glBegin(GL_LINES); for(i = 0; i < dm->numEdgeData; i++, medge++) { - if((medge->flag&ME_EDGEDRAW) + if((drawAllEdges || (medge->flag&ME_EDGEDRAW)) && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) { glVertex3fv(mvert[medge->v1].co); glVertex3fv(mvert[medge->v2].co); @@ -317,7 +328,7 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) GPU_edge_setup(dm); if( !GPU_buffer_legacy(dm) ) { for(i = 0; i < dm->numEdgeData; i++, medge++) { - if((medge->flag&ME_EDGEDRAW) + if((drawAllEdges || (medge->flag&ME_EDGEDRAW)) && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) { draw = 1; } @@ -1354,7 +1365,6 @@ static void cdDM_foreachMappedFaceCenter( static void cdDM_free_internal(CDDerivedMesh *cddm) { - if(cddm->pbvh) BLI_pbvh_free(cddm->pbvh); if(cddm->fmap) MEM_freeN(cddm->fmap); if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem); } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index ad1fb80801f..e0aa47eac88 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -68,6 +68,7 @@ #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_object.h" +#include "BKE_paint.h" #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_scene.h" @@ -9064,10 +9065,10 @@ static DerivedMesh *multiresModifier_applyModifier(ModifierData *md, Object *ob, result->release(result); result= cddm; } - else if(ob->mode & OB_MODE_SCULPT) { + else if((ob->mode & OB_MODE_SCULPT) && ob->sculpt) { /* would be created on the fly too, just nicer this way on first stroke after e.g. switching levels */ - result->getPBVH(ob, result); + ob->sculpt->pbvh= result->getPBVH(ob, result); } return result; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 0d508a4c4d1..c70d12bcb75 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -34,14 +34,15 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_math.h" #include "BLI_pbvh.h" #include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_multires.h" +#include "BKE_paint.h" #include "BKE_scene.h" #include "BKE_subsurf.h" #include "BKE_utildefines.h" @@ -109,11 +110,16 @@ void multires_mark_as_modified(Object *ob) void multires_force_update(Object *ob) { - - if(ob && ob->derivedFinal) { - ob->derivedFinal->needsFree =1; - ob->derivedFinal->release(ob->derivedFinal); - ob->derivedFinal = NULL; + if(ob) { + if(ob->derivedFinal) { + ob->derivedFinal->needsFree =1; + ob->derivedFinal->release(ob->derivedFinal); + ob->derivedFinal = NULL; + } + if(ob->sculpt && ob->sculpt->pbvh) { + BLI_pbvh_free(ob->sculpt->pbvh); + ob->sculpt->pbvh= NULL; + } } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index b1cb83c0a51..64abffa5119 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -58,8 +58,9 @@ #include "DNA_world_types.h" #include "BLI_blenlib.h" -#include "BLI_math.h" #include "BLI_editVert.h" +#include "BLI_math.h" +#include "BLI_pbvh.h" #include "BKE_utildefines.h" @@ -231,23 +232,26 @@ void object_free_display(Object *ob) freedisplist(&ob->disp); } -void free_sculptsession(SculptSession **ssp) +void free_sculptsession(Object *ob) { - if(ssp && *ssp) { - SculptSession *ss = *ssp; + if(ob && ob->sculpt) { + SculptSession *ss = ob->sculpt; + DerivedMesh *dm= ob->derivedFinal; + + if(ss->pbvh) + BLI_pbvh_free(ss->pbvh); + if(dm && dm->getPBVH) + dm->getPBVH(NULL, dm); /* signal to clear */ if(ss->texcache) MEM_freeN(ss->texcache); - if(ss->layer_disps) - MEM_freeN(ss->layer_disps); - if(ss->layer_co) MEM_freeN(ss->layer_co); MEM_freeN(ss); - *ssp = NULL; + ob->sculpt = NULL; } } @@ -306,7 +310,7 @@ void free_object(Object *ob) if(ob->bsoft) bsbFree(ob->bsoft); if(ob->gpulamp.first) GPU_lamp_free(ob); - free_sculptsession(&ob->sculpt); + free_sculptsession(ob); if(ob->pc_ids.first) BLI_freelistN(&ob->pc_ids); } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 937351b4992..0cc574984b8 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -42,11 +42,12 @@ #include "DNA_scene_types.h" #include "BKE_cdderivedmesh.h" -#include "BKE_utildefines.h" #include "BKE_global.h" #include "BKE_mesh.h" +#include "BKE_paint.h" #include "BKE_scene.h" #include "BKE_subsurf.h" +#include "BKE_utildefines.h" #include "BLI_blenlib.h" #include "BLI_edgehash.h" @@ -1114,7 +1115,7 @@ static void ccgDM_drawVerts(DerivedMesh *dm) { ccgFaceIterator_free(fi); glEnd(); } -static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) { +static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); @@ -1219,7 +1220,7 @@ static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d) static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm) { - if(ccgdm->pbvh) { + if(ccgdm->pbvh && ccgdm->multires.mmd) { CCGFace **faces; int totface; @@ -1935,12 +1936,13 @@ static void ccgDM_release(DerivedMesh *dm) { ccgdm->multires.update(dm); } - if(ccgdm->pbvh) BLI_pbvh_free(ccgdm->pbvh); if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces); if(ccgdm->gridData) MEM_freeN(ccgdm->gridData); if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency); if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset); if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss); + if(ccgdm->fmap) MEM_freeN(ccgdm->fmap); + if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem); MEM_freeN(ccgdm->edgeFlags); MEM_freeN(ccgdm->faceFlags); MEM_freeN(ccgdm->vertMap); @@ -2185,11 +2187,35 @@ static int *ccgDM_getGridOffset(DerivedMesh *dm) return ccgdm->gridOffset; } +static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm) +{ + CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; + + if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) { + Mesh *me= ob->data; + + create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface, + me->totvert, me->totface); + } + + return ccgdm->fmap; +} + static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) { CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; int gridSize, numGrids; + if(!ob) { + ccgdm->pbvh= NULL; + return NULL; + } + + if(!ob->sculpt) + return NULL; + if(ob->sculpt->pbvh) + ccgdm->pbvh= ob->sculpt->pbvh; + if(ccgdm->pbvh) return ccgdm->pbvh; @@ -2199,14 +2225,14 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) gridSize = ccgDM_getGridSize(dm); numGrids = ccgDM_getNumGrids(dm); - ccgdm->pbvh = BLI_pbvh_new(); + ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, numGrids, gridSize, (void**)ccgdm->gridFaces); } else if(ob->type == OB_MESH) { Mesh *me= ob->data; - ccgdm->pbvh = BLI_pbvh_new(); + ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert, me->totface, me->totvert); } @@ -2265,6 +2291,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, ccgdm->dm.getGridData = ccgDM_getGridData; ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency; ccgdm->dm.getGridOffset = ccgDM_getGridOffset; + ccgdm->dm.getFaceMap = ccgDM_getFaceMap; ccgdm->dm.getPBVH = ccgDM_getPBVH; ccgdm->dm.getVertCos = ccgdm_getVertCos; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 45a64af6dbd..3d30b24723e 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -375,7 +375,7 @@ void ED_region_tag_redraw(ARegion *ar) { if(ar) { /* zero region means full region redraw */ - ar->do_draw= 1; + ar->do_draw= RGN_DRAW; memset(&ar->drawrct, 0, sizeof(ar->drawrct)); } } @@ -385,7 +385,7 @@ void ED_region_tag_redraw_partial(ARegion *ar, rcti *rct) if(ar) { if(!ar->do_draw) { /* no redraw set yet, set partial region */ - ar->do_draw= 1; + ar->do_draw= RGN_DRAW_PARTIAL; ar->drawrct= *rct; } else if(ar->drawrct.xmin != ar->drawrct.xmax) { diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 94814203a4c..effe3cb1428 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -133,6 +133,7 @@ typedef struct StrokeCache { float radius; float true_location[3]; float location[3]; + float flip; float pressure; float mouse[2]; @@ -193,18 +194,16 @@ static void projectf(bglMats *mats, const float v[3], float p[2]) int sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d, Object *ob, rcti *rect) { - /* can't use ob->sculpt->tree, only valid during sculpt */ - DerivedMesh *dm= ob->derivedFinal; - PBVH *tree= (dm)? dm->getPBVH(ob, dm): NULL; + PBVH *pbvh= ob->sculpt->pbvh; float bb_min[3], bb_max[3], pmat[4][4]; int i, j, k; view3d_get_object_project_mat(rv3d, ob, pmat); - if(!tree) + if(!pbvh) return 0; - BLI_pbvh_redraw_BB(tree, bb_min, bb_max); + BLI_pbvh_redraw_BB(pbvh, bb_min, bb_max); rect->xmin = rect->ymin = INT_MAX; rect->xmax = rect->ymax = INT_MIN; @@ -234,8 +233,7 @@ int sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d, void sculpt_get_redraw_planes(float planes[4][4], ARegion *ar, RegionView3D *rv3d, Object *ob) { - DerivedMesh *dm= ob->derivedFinal; - PBVH *tree= (dm)? dm->getPBVH(ob, dm): NULL; + PBVH *pbvh= ob->sculpt->pbvh; BoundBox *bb = MEM_callocN(sizeof(BoundBox), "sculpt boundbox"); bglMats mats; rcti rect; @@ -264,8 +262,8 @@ void sculpt_get_redraw_planes(float planes[4][4], ARegion *ar, MEM_freeN(bb); /* clear redraw flag from nodes */ - if(tree) - BLI_pbvh_update(tree, PBVH_UpdateRedraw, NULL); + if(pbvh) + BLI_pbvh_update(pbvh, PBVH_UpdateRedraw, NULL); } /************************** Undo *************************/ @@ -289,6 +287,9 @@ typedef struct SculptUndoNode { int gridsize; /* same for grid */ int totgrid; /* to restore into right location */ int *grids; /* to restore into right location */ + + /* layer brush */ + float *layer_disp; } SculptUndoNode; static void update_cb(PBVHNode *node, void *data) @@ -296,6 +297,20 @@ static void update_cb(PBVHNode *node, void *data) BLI_pbvh_node_mark_update(node); } +/* Checks whether full update mode (slower) needs to be used to work with modifiers */ +static int sculpt_modifiers_active(Scene *scene, Object *ob) +{ + ModifierData *md; + + for(md= modifiers_getVirtualModifierList(ob); md; md= md->next) { + if(modifier_isEnabled(scene, md, eModifierMode_Realtime)) + if(!ELEM(md->type, eModifierType_Multires, eModifierType_ShapeKey)) + return 1; + } + + return 0; +} + static void sculpt_undo_restore(bContext *C, ListBase *lb) { Scene *scene = CTX_data_scene(C); @@ -327,7 +342,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb) mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE; } } - else if(unode->maxgrid) { + else if(unode->maxgrid && dm->getGridData) { /* multires restore */ DMGridData **grids, *grid; float (*co)[3]; @@ -360,11 +375,14 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb) /* we update all nodes still, should be more clever, but also needs to work correct when exiting/entering sculpt mode and the nodes get recreated, though in that case it could do all */ - BLI_pbvh_search_callback(ss->tree, NULL, NULL, update_cb, NULL); - BLI_pbvh_update(ss->tree, PBVH_UpdateBB|PBVH_UpdateOriginalBB|PBVH_UpdateRedraw, NULL); + BLI_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, NULL); + BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB|PBVH_UpdateOriginalBB|PBVH_UpdateRedraw, NULL); if((mmd=sculpt_multires_active(ob))) multires_mark_as_modified(ob); + + if(sculpt_modifiers_active(scene, ob)) + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } @@ -381,6 +399,8 @@ static void sculpt_undo_free(ListBase *lb) MEM_freeN(unode->index); if(unode->grids) MEM_freeN(unode->grids); + if(unode->layer_disp) + MEM_freeN(unode->layer_disp); } } @@ -418,8 +438,8 @@ static SculptUndoNode *sculpt_undo_push_node(SculptSession *ss, PBVHNode *node) strcpy(unode->idname, ob->id.name); unode->node= node; - BLI_pbvh_node_num_verts(ss->tree, node, &totvert, &allvert); - BLI_pbvh_node_get_grids(ss->tree, node, &grids, &totgrid, + BLI_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert); + BLI_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid, &maxgrid, &gridsize, NULL, NULL); unode->totvert= totvert; @@ -448,7 +468,7 @@ static SculptUndoNode *sculpt_undo_push_node(SculptSession *ss, PBVHNode *node) { PBVHVertexIter vd; - BLI_pbvh_vertex_iter_begin(ss->tree, node, vd, PBVH_ITER_ALL) { + BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) { copy_v3_v3(unode->co[vd.i], vd.co); if(vd.no) VECCOPY(unode->no[vd.i], vd.no) else normal_float_to_short_v3(unode->no[vd.i], vd.fno); @@ -480,6 +500,11 @@ static void sculpt_undo_push_end(SculptSession *ss) MEM_freeN(unode->no); unode->no= NULL; } + + if(unode->layer_disp) { + MEM_freeN(unode->layer_disp); + unode->layer_disp= NULL; + } } undo_paint_push_end(UNDO_PAINT_MESH); @@ -708,7 +733,7 @@ static int sculpt_search_sphere_cb(PBVHNode *node, void *data_v) BLI_pbvh_node_get_original_BB(node, bb_min, bb_max); else BLI_pbvh_node_get_BB(node, bb_min, bb_max); - + for(i = 0; i < 3; ++i) { if(bb_min[i] > center[i]) nearest[i] = bb_min[i]; @@ -751,7 +776,7 @@ static void add_norm_if(float view_vec[3], float out[3], float out_flip[3], floa /* For draw/layer/flatten; finds average normal for all active vertices */ static void calc_area_normal(Sculpt *sd, SculptSession *ss, float area_normal[3], PBVHNode **nodes, int totnode) { - PBVH *bvh= ss->tree; + PBVH *bvh= ss->pbvh; StrokeCache *cache = ss->cache; const int view = 0; /* XXX: should probably be a flag, not number: brush_type==SCULPT_TOOL_DRAW ? sculptmode_brush()->view : 0; */ float out[3] = {0.0f, 0.0f, 0.0f}; @@ -845,7 +870,7 @@ static void do_draw_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t sculpt_undo_push_node(ss, nodes[n]); sculpt_brush_test_init(ss, &test); - BLI_pbvh_vertex_iter_begin(ss->tree, nodes[n], vd, PBVH_ITER_UNIQUE) { + BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { /* offset vertex */ float fade = tex_strength(ss, brush, vd.co, test.dist); @@ -916,7 +941,7 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node) sculpt_brush_test_init(ss, &test); - BLI_pbvh_vertex_iter_begin(ss->tree, node, vd, PBVH_ITER_UNIQUE) { + BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { float fade = tex_strength(ss, brush, vd.co, test.dist)*bstrength; float avg[3], val[3]; @@ -948,7 +973,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no sculpt_brush_test_init(ss, &test); - BLI_pbvh_node_get_grids(ss->tree, node, &grid_indices, &totgrid, + BLI_pbvh_node_get_grids(ss->pbvh, node, &grid_indices, &totgrid, NULL, &gridsize, &griddata, &gridadj); #pragma omp critical @@ -1050,13 +1075,13 @@ static void do_pinch_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int sculpt_undo_push_node(ss, nodes[n]); sculpt_brush_test_init(ss, &test); - BLI_pbvh_vertex_iter_begin(ss->tree, nodes[n], vd, PBVH_ITER_UNIQUE) { + BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { float fade = tex_strength(ss, brush, vd.co, test.dist)*bstrength; float val[3]= {vd.co[0]+(test.location[0]-vd.co[0])*fade, vd.co[1]+(test.location[1]-vd.co[1])*fade, vd.co[2]+(test.location[2]-vd.co[2])*fade}; - + sculpt_clip(sd, ss, vd.co, val); if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE; } @@ -1085,7 +1110,7 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t origco= sculpt_undo_push_node(ss, nodes[n])->co; sculpt_brush_test_init(ss, &test); - BLI_pbvh_vertex_iter_begin(ss->tree, nodes[n], vd, PBVH_ITER_UNIQUE) { + BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, origco[vd.i])) { float fade = tex_strength(ss, brush, origco[vd.i], test.dist)*bstrength; float add[3]= {vd.co[0]+fade*grab_delta[0], @@ -1110,10 +1135,6 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int float lim= ss->cache->radius / 4; int n; - /* XXX not working yet for multires */ - if(ss->multires) - return; - if(ss->cache->flip) lim = -lim; @@ -1127,16 +1148,21 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int for(n=0; nco; + unode= sculpt_undo_push_node(ss, nodes[n]); + origco=unode->co; + if(!unode->layer_disp) + unode->layer_disp= MEM_callocN(sizeof(float)*unode->totvert, "layer disp"); + layer_disp= unode->layer_disp; + sculpt_brush_test_init(ss, &test); - BLI_pbvh_vertex_iter_begin(ss->tree, nodes[n], vd, PBVH_ITER_UNIQUE) { + BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { float fade = tex_strength(ss, brush, vd.co, test.dist)*bstrength; - int index= vd.vert_indices[vd.i]; - float *disp= &ss->layer_disps[index]; + float *disp= &layer_disp[vd.i]; float val[3]; *disp+= fade; @@ -1146,6 +1172,8 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int *disp = lim; if(ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) { + int index= vd.vert_indices[vd.i]; + /* persistent base */ val[0] = ss->layer_co[index][0] + (*disp)*offset[0]; val[1] = ss->layer_co[index][1] + (*disp)*offset[1]; @@ -1181,7 +1209,7 @@ static void do_inflate_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, in sculpt_undo_push_node(ss, nodes[n]); sculpt_brush_test_init(ss, &test); - BLI_pbvh_vertex_iter_begin(ss->tree, nodes[n], vd, PBVH_ITER_UNIQUE) { + BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { float fade = tex_strength(ss, brush, vd.co, test.dist)*bstrength; float add[3]; @@ -1225,7 +1253,7 @@ static void calc_flatten_center(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, sculpt_undo_push_node(ss, nodes[n]); sculpt_brush_test_init(ss, &test); - BLI_pbvh_vertex_iter_begin(ss->tree, nodes[n], vd, PBVH_ITER_UNIQUE) { + BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { for(j = 0; j < FLATTEN_SAMPLE_SIZE; ++j) { if(test.dist > outer_dist[j]) { @@ -1297,7 +1325,7 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, PBVHNode **node flip = bstr < 0; } - #pragma omp parallel for private(n) schedule(static) + //#pragma omp parallel for private(n) schedule(static) for(n=0; ntree, nodes[n], vd, PBVH_ITER_UNIQUE) { + BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { float intr[3], val[3]; @@ -1358,7 +1386,7 @@ static void do_brush_action(Sculpt *sd, SculptSession *ss, StrokeCache *cache) area of influence */ if(brush->sculpt_tool == SCULPT_TOOL_GRAB) { data.original= 1; - BLI_pbvh_search_gather(ss->tree, sculpt_search_sphere_cb, &data, + BLI_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode); if(cache->first_time) @@ -1367,7 +1395,7 @@ static void do_brush_action(Sculpt *sd, SculptSession *ss, StrokeCache *cache) copy_v3_v3(ss->cache->location, ss->cache->grab_active_location[ss->cache->symmetry]); } else { - BLI_pbvh_search_gather(ss->tree, sculpt_search_sphere_cb, &data, + BLI_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode); } @@ -1458,20 +1486,6 @@ static void sculpt_update_tex(Sculpt *sd, SculptSession *ss) } } -/* Checks whether full update mode (slower) needs to be used to work with modifiers */ -static int sculpt_modifiers_active(Scene *scene, Object *ob) -{ - ModifierData *md; - - for(md= modifiers_getVirtualModifierList(ob); md; md= md->next) { - if(modifier_isEnabled(scene, md, eModifierMode_Realtime)) - if(!ELEM(md->type, eModifierType_Multires, eModifierType_ShapeKey)) - return 1; - } - - return 0; -} - /* Sculpt mode handles multires differently from regular meshes, but only if it's the last modifier on the stack and it is not on the first level */ struct MultiresModifierData *sculpt_multires_active(Object *ob) @@ -1546,7 +1560,7 @@ void sculpt_update_mesh_elements(Scene *scene, Object *ob, int need_fmap) ss->face_normals = NULL; } - ss->tree = dm->getPBVH(ob, dm); + ss->pbvh = dm->getPBVH(ob, dm); ss->fmap = (need_fmap && dm->getFaceMap)? dm->getFaceMap(ob, dm): NULL; } @@ -1684,16 +1698,13 @@ static void sculpt_update_cache_invariants(Sculpt *sd, SculptSession *ss, bConte view3d_get_transformation(vc->ar, vc->rv3d, vc->obact, cache->mats); /* Initialize layer brush displacements and persistent coords */ - if(brush->sculpt_tool == SCULPT_TOOL_LAYER && !ss->multires) { - if(!ss->layer_disps || !(brush->flag & BRUSH_PERSISTENT)) { - if(ss->layer_disps) - MEM_freeN(ss->layer_disps); - ss->layer_disps = MEM_callocN(sizeof(float) * ss->totvert, "layer brush displacements"); - } - if(!ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) { + if(brush->sculpt_tool == SCULPT_TOOL_LAYER) { + /* not supported yet for multires */ + if(!ss->multires && !ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) { if(!ss->layer_co) ss->layer_co= MEM_mallocN(sizeof(float) * 3 * ss->totvert, "sculpt mesh vertices copy"); + for(i = 0; i < ss->totvert; ++i) copy_v3_v3(ss->layer_co[i], ss->mvert[i].co); } @@ -1779,17 +1790,27 @@ static void sculpt_update_cache_variants(Sculpt *sd, SculptSession *ss, struct P /* Find the grab delta */ if(brush->sculpt_tool == SCULPT_TOOL_GRAB) { - float grab_location[3]; + float grab_location[3], imat[4][4]; if(cache->first_time) copy_v3_v3(cache->orig_grab_location, cache->true_location); - initgrabz(cache->vc->rv3d, cache->orig_grab_location[0], cache->orig_grab_location[1], cache->orig_grab_location[2]); + /* compute 3d coordinate at same z from original location + mouse */ + initgrabz(cache->vc->rv3d, cache->orig_grab_location[0], + cache->orig_grab_location[1], cache->orig_grab_location[2]); window_to_3d_delta(cache->vc->ar, grab_location, cache->mouse[0], cache->mouse[1]); - if(!cache->first_time) + /* compute delta to move verts by */ + if(!cache->first_time) { sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location); + invert_m4_m4(imat, ss->ob->obmat); + mul_mat3_m4_v3(imat, cache->grab_delta); + } + copy_v3_v3(cache->old_grab_location, grab_location); + + /* location stays the same for finding vertices in brush radius */ + copy_v3_v3(cache->true_location, cache->orig_grab_location); } } @@ -1824,7 +1845,7 @@ void sculpt_raycast_cb(PBVHNode *node, void *data_v) origco= (unode)? unode->co: NULL; } - srd->hit |= BLI_pbvh_node_raycast(srd->ss->tree, node, origco, + srd->hit |= BLI_pbvh_node_raycast(srd->ss->pbvh, node, origco, srd->ray_start, srd->ray_normal, &srd->dist); } @@ -1860,7 +1881,7 @@ int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float ou srd.dist = dist; srd.hit = 0; srd.original = (cache)? cache->original: 0; - BLI_pbvh_raycast(ss->tree, sculpt_raycast_cb, &srd, + BLI_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd, ray_start, ray_normal, srd.original); copy_v3_v3(out, ray_normal); @@ -1943,7 +1964,7 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss) PBVHNode **nodes; int n, totnode; - BLI_pbvh_search_gather(ss->tree, NULL, NULL, &nodes, &totnode); + BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); #pragma omp parallel for private(n) schedule(static) for(n=0; ntree, nodes[n], vd, PBVH_ITER_UNIQUE) { + BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { copy_v3_v3(vd.co, unode->co[vd.i]); if(vd.no) VECCOPY(vd.no, unode->no[vd.i]) else normal_short_to_float_v3(vd.fno, unode->no[vd.i]); @@ -1967,9 +1988,6 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss) for(i = 0; i < ss->totface; ++i, fn += 3) copy_v3_v3(fn, cache->face_norms[i]); } - - if(brush->sculpt_tool == SCULPT_TOOL_LAYER && !ss->multires) - memset(ss->layer_disps, 0, sizeof(float) * ss->totvert); } } @@ -1992,7 +2010,7 @@ static void sculpt_flush_update(bContext *C) else { rcti r; - BLI_pbvh_update(ss->tree, PBVH_UpdateBB, NULL); + BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB, NULL); redraw = sculpt_get_redraw_rect(ar, CTX_wm_region_view3d(C), ob, &r); if(redraw) { @@ -2067,7 +2085,7 @@ static void sculpt_stroke_done(bContext *C, struct PaintStroke *stroke) sculpt_undo_push_end(ss); - BLI_pbvh_update(ss->tree, PBVH_UpdateOriginalBB, NULL); + BLI_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL); if(ss->refkb) sculpt_key_to_mesh(ss->refkb, ob); @@ -2177,10 +2195,6 @@ static int sculpt_set_persistent_base(bContext *C, wmOperator *op) SculptSession *ss = CTX_data_active_object(C)->sculpt; if(ss) { - if(ss->layer_disps) - MEM_freeN(ss->layer_disps); - ss->layer_disps = NULL; - if(ss->layer_co) MEM_freeN(ss->layer_co); ss->layer_co = NULL; @@ -2231,7 +2245,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op) /* Leave sculptmode */ ob->mode &= ~OB_MODE_SCULPT; - free_sculptsession(&ob->sculpt); + free_sculptsession(ob); } else { /* Enter sculptmode */ @@ -2246,7 +2260,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op) /* Create sculpt mode session data */ if(ob->sculpt) - free_sculptsession(&ob->sculpt); + free_sculptsession(ob); sculpt_init_session(scene, ob); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index b7de750e601..fa304c3ea8b 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2237,7 +2237,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object else { if (cageDM!=finalDM) { UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7); - finalDM->drawEdges(finalDM, 1); + finalDM->drawEdges(finalDM, 1, 0); } } @@ -2359,7 +2359,7 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm) GPU_disable_material(); } else { - dm->drawEdges(dm, 0); + dm->drawEdges(dm, 0, 1); } glLineWidth(1.0); @@ -2459,7 +2459,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0x8888); - dm->drawEdges(dm, 1); + dm->drawEdges(dm, 1, 0); bglPolygonOffset(rv3d->dist, 0.0); glDepthMask(1); @@ -2486,9 +2486,11 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D int fast= (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING); if(ob->sculpt->partial_redraw) { - sculpt_get_redraw_planes(planes, ar, rv3d, ob); - fpl = planes; - ob->sculpt->partial_redraw = 0; + if(ar->do_draw & RGN_DRAW_PARTIAL) { + sculpt_get_redraw_planes(planes, ar, rv3d, ob); + fpl = planes; + ob->sculpt->partial_redraw = 0; + } } dm->drawFacesSolid(dm, fpl, fast, GPU_enable_material); @@ -2627,7 +2629,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D glDepthMask(0); // disable write in zbuffer, selected edge wires show better } - dm->drawEdges(dm, (dt==OB_WIRE || totface==0)); + dm->drawEdges(dm, (dt==OB_WIRE || totface==0), 0); if (dt!=OB_WIRE && draw_wire==2) { glDepthMask(1); @@ -2970,7 +2972,7 @@ static void drawDispListshaded(ListBase *lb, Object *ob) static void drawCurveDMWired(Object *ob) { DerivedMesh *dm = ob->derivedFinal; - dm->drawEdges (dm, 1); + dm->drawEdges (dm, 1, 0); } /* return 1 when nothing was drawn */ @@ -6314,9 +6316,9 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r if(dt<=OB_WIRE) { if(dm) - dm->drawEdges(dm, 1); + dm->drawEdges(dm, 1, 0); else if(edm) - edm->drawEdges(edm, 1); + edm->drawEdges(edm, 1, 0); } else { if(outline) diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index ce165c0bac8..6d73c261f23 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -244,5 +244,9 @@ enum { #define RGN_FLAG_HIDDEN 1 #define RGN_FLAG_TOO_SMALL 2 +/* region do_draw */ +#define RGN_DRAW 1 +#define RGN_DRAW_PARTIAL 2 + #endif diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index b6840af9779..fec46d32a08 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -158,7 +158,7 @@ static void wm_flush_regions_down(bScreen *screen, rcti *dirty) for(sa= screen->areabase.first; sa; sa= sa->next) { for(ar= sa->regionbase.first; ar; ar= ar->next) { if(BLI_isect_rcti(dirty, &ar->winrct, NULL)) { - ar->do_draw= 1; + ar->do_draw= RGN_DRAW; memset(&ar->drawrct, 0, sizeof(ar->drawrct)); ar->swap= WIN_NONE_OK; } @@ -173,7 +173,7 @@ static void wm_flush_regions_up(bScreen *screen, rcti *dirty) for(ar= screen->regionbase.first; ar; ar= ar->next) { if(BLI_isect_rcti(dirty, &ar->winrct, NULL)) { - ar->do_draw= 1; + ar->do_draw= RGN_DRAW; memset(&ar->drawrct, 0, sizeof(ar->drawrct)); ar->swap= WIN_NONE_OK; } @@ -681,6 +681,13 @@ static int wm_automatic_draw_method(wmWindow *win) return win->drawmethod; } +void wm_tag_redraw_overlay(wmWindow *win, ARegion *ar) +{ + /* for draw triple gestures, paint cursors don't need region redraw */ + if(ar && win && wm_automatic_draw_method(win) != USER_DRAW_TRIPLE) + ED_region_tag_redraw(ar); +} + void wm_draw_update(bContext *C) { wmWindowManager *wm= CTX_wm_manager(C); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 5de01a6259f..d430b0f8a1b 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -71,6 +71,7 @@ #include "wm_window.h" #include "wm_event_system.h" #include "wm_event_types.h" +#include "wm_draw.h" /* ************ event management ************** */ @@ -1460,9 +1461,7 @@ static void wm_paintcursor_tag(bContext *C, wmPaintCursor *pc, ARegion *ar) if(pc->poll == NULL || pc->poll(C)) { wmWindow *win= CTX_wm_window(C); win->screen->do_draw_paintcursor= 1; - - if(win->drawmethod != USER_DRAW_TRIPLE) - ED_region_tag_redraw(ar); + wm_tag_redraw_overlay(win, ar); } } } diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index e26d4dd8473..2365da517e7 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -47,6 +47,7 @@ #include "wm.h" #include "wm_event_system.h" #include "wm_subwindow.h" +#include "wm_draw.h" #include "ED_screen.h" @@ -346,8 +347,8 @@ void wm_gesture_tag_redraw(bContext *C) if(screen) screen->do_draw_gesture= 1; - if(ar && win->drawmethod != USER_DRAW_TRIPLE) - ED_region_tag_redraw(ar); + + wm_tag_redraw_overlay(win, ar); } diff --git a/source/blender/windowmanager/wm_draw.h b/source/blender/windowmanager/wm_draw.h index 42d3ec7e8bc..762d759c936 100644 --- a/source/blender/windowmanager/wm_draw.h +++ b/source/blender/windowmanager/wm_draw.h @@ -38,5 +38,7 @@ void wm_draw_update (struct bContext *C); void wm_draw_window_clear (struct wmWindow *win); void wm_draw_region_clear (struct wmWindow *win, struct ARegion *ar); +void wm_tag_redraw_overlay (struct wmWindow *win, struct ARegion *ar); + #endif /* WM_DRAW_H */