projection painting changes from 2.4x r23600
authorCampbell Barton <ideasman42@gmail.com>
Fri, 2 Oct 2009 07:03:58 +0000 (07:03 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 2 Oct 2009 07:03:58 +0000 (07:03 +0000)
source/blender/editors/mesh/editface.c
source/blender/editors/sculpt_paint/paint_image.c

index a6c5e5beccf051fc0ba5d4cc5736c48487ecb63d..f65ab7ddd67d9f2afe0caec479fe25bdcf81ca3e 100644 (file)
@@ -89,6 +89,34 @@ static int pupmenu() {return 0;}
 /* ***************** XXX **************** */
 
 
+/* copy the face flags, most importantly selection from the mesh to the final derived mesh,
+ * use in object mode when selecting faces (while painting) */
+void object_facesel_flush_dm(Object *ob)
+{
+       Mesh *me= get_mesh(ob);
+       DerivedMesh *dm= ob->derivedFinal;
+       MFace *faces, *mf, *mf_orig;
+       int *index_array = NULL;
+       int totface;
+       int i;
+       
+       
+       if(me==NULL || dm==NULL || !CustomData_has_layer( &dm->faceData, CD_ORIGINDEX))
+               return;
+       
+       faces = dm->getFaceArray(dm);
+       totface = dm->getNumFaces(dm);
+       
+       index_array = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+       
+       mf= faces;
+       
+       for (i= 0; i<totface; i++, mf++) { /* loop over derived mesh faces */
+               mf_orig= me->mface + index_array[i];
+               mf->flag= mf_orig->flag;;
+       }
+}
+
 /* returns 0 if not found, otherwise 1 */
 int facesel_face_pick(View3D *v3d, Mesh *me, short *mval, unsigned int *index, short rect)
 {
@@ -163,6 +191,7 @@ void reveal_tface(Scene *scene)
                mface++;
        }
 
+       object_facesel_flush_dm(OBACT);
 // XXX notifier!       object_tface_flags_changed(OBACT, 0);
 }
 
@@ -197,7 +226,8 @@ void hide_tface(Scene *scene)
                
                mface++;
        }
-
+       
+       object_facesel_flush_dm(OBACT);
 // XXX notifier!               object_tface_flags_changed(OBACT, 0);
 }
 
@@ -237,7 +267,10 @@ void deselectall_tface(Scene *scene)
        sel= 0;
        while(a--) {
                if(mface->flag & ME_HIDE);
-               else if(mface->flag & ME_FACE_SEL) sel= 1;
+               else if(mface->flag & ME_FACE_SEL) {
+                       sel= 1;
+                       break;
+               }
                mface++;
        }
        
@@ -252,6 +285,7 @@ void deselectall_tface(Scene *scene)
                mface++;
        }
 
+       object_facesel_flush_dm(OBACT);
 // XXX notifier!               object_tface_flags_changed(OBACT, 0);
 }
 
@@ -274,7 +308,8 @@ void selectswap_tface(Scene *scene)
                }
                mface++;
        }
-
+       
+       object_facesel_flush_dm(OBACT);
 // XXX notifier!               object_tface_flags_changed(OBACT, 0);
 }
 
@@ -655,11 +690,11 @@ void face_select(Scene *scene, View3D *v3d)
        
        /* image window redraw */
        
-
+       object_facesel_flush_dm(OBACT);
 // XXX notifier!               object_tface_flags_changed(OBACT, 1);
 }
 
-void face_borderselect(Scene *scene, ARegion *ar)
+void face_borderselect(Scene *scene, ScrArea *sa, ARegion *ar)
 {
        Mesh *me;
        MFace *mface;
@@ -675,13 +710,18 @@ void face_borderselect(Scene *scene, ARegion *ar)
        
 // XXX val= get_border(&rect, 3);
        
-       /* why readbuffer here? shouldn't be necessary (maybe a flush or so) */
-       glReadBuffer(GL_BACK);
-#ifdef __APPLE__
-       glReadBuffer(GL_AUX0); /* apple only */
-#endif
-       
        if(val) {
+               View3D *v3d= sa->spacedata.first;
+               RegionView3D *rv3d= ar->regiondata;
+
+               /* without this border select often fails */
+#if 0 /* XXX untested in 2.5 */
+               if (v3d->flag & V3D_NEEDBACKBUFDRAW) {
+                       check_backbuf();
+                       persp(PERSP_VIEW);
+               }
+#endif
+               
                selar= MEM_callocN(me->totface+1, "selar");
                
                sx= (rect.xmax-rect.xmin+1);
@@ -722,6 +762,8 @@ void face_borderselect(Scene *scene, ARegion *ar)
 #ifdef __APPLE__       
        glReadBuffer(GL_BACK);
 #endif
+       
+       object_facesel_flush_dm(OBACT);
 }
 
 
index d223c4236906761307d2a34f82035ab14f44c44d..7596191e781d5a2f7e988bd4481fc45d7da47482 100644 (file)
@@ -223,6 +223,7 @@ typedef struct ProjPaintState {
        DerivedMesh    *dm;
        int                     dm_totface;
        int                     dm_totvert;
+       int                             dm_release;
        
        MVert              *dm_mvert;
        MFace              *dm_mface;
@@ -2934,12 +2935,26 @@ static void project_paint_begin(ProjPaintState *ps)
        /* ---- end defines ---- */
        
        /* paint onto the derived mesh */
-       ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->v3d->customdata_mask);
+       
+       /* Workaround for subsurf selection, try the display mesh first */
+       if(ps->ob->derivedFinal && CustomData_has_layer( &ps->ob->derivedFinal->faceData, CD_MTFACE)) {
+               ps->dm = ps->ob->derivedFinal;
+               ps->dm_release= FALSE;
+       }
+       else {
+               ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->v3d->customdata_mask);
+               ps->dm_release= TRUE;
+       }
        
        if ( !CustomData_has_layer( &ps->dm->faceData, CD_MTFACE) ) {
+               
+               if(ps->dm_release)
+                       ps->dm->release(ps->dm);
+               
                ps->dm = NULL;
                return; 
        }
+       
        ps->dm_mvert = ps->dm->getVertArray(ps->dm);
        ps->dm_mface = ps->dm->getFaceArray(ps->dm);
        ps->dm_mtface= ps->dm->getFaceDataArray(ps->dm, CD_MTFACE);
@@ -3402,7 +3417,8 @@ static void project_paint_end(ProjPaintState *ps)
                BLI_memarena_free(ps->arena_mt[a]);
        }
        
-       ps->dm->release(ps->dm);
+       if(ps->dm_release)
+               ps->dm->release(ps->dm);
 }
 
 /* 1= an undo, -1 is a redo. */