[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20798] branches/soc-2009-yukishiro/source /blender: undo & redo for light paint.

Jingyuan Huang jingyuan.huang at gmail.com
Thu Jun 11 02:46:42 CEST 2009


Revision: 20798
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20798
Author:   yukishiro
Date:     2009-06-11 02:46:42 +0200 (Thu, 11 Jun 2009)

Log Message:
-----------
undo & redo for light paint. still needs improvement

Modified Paths:
--------------
    branches/soc-2009-yukishiro/source/blender/blenkernel/intern/cdderivedmesh.c
    branches/soc-2009-yukishiro/source/blender/editors/include/ED_sculpt.h
    branches/soc-2009-yukishiro/source/blender/editors/sculpt_paint/paint_light.c
    branches/soc-2009-yukishiro/source/blender/editors/space_view3d/drawobject.c
    branches/soc-2009-yukishiro/source/blender/editors/util/ed_util.c
    branches/soc-2009-yukishiro/source/blender/editors/util/undo.c

Modified: branches/soc-2009-yukishiro/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- branches/soc-2009-yukishiro/source/blender/blenkernel/intern/cdderivedmesh.c	2009-06-10 22:03:50 UTC (rev 20797)
+++ branches/soc-2009-yukishiro/source/blender/blenkernel/intern/cdderivedmesh.c	2009-06-11 00:46:42 UTC (rev 20798)
@@ -484,8 +484,10 @@
 	MFace *mf = cddm->mface;
 	MCol *mc;
 	float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
-	int i, orig, *index=0;// TODO = DM_get_face_data_layer(dm, CD_ORIGINDEX);
+	int i, orig, *index=0;
 
+        if (!(G.f & G_LIGHTPAINT)) index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
+
 	mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL);
 	if(!mc)
 		mc = DM_get_face_data_layer(dm, CD_MCOL);

Modified: branches/soc-2009-yukishiro/source/blender/editors/include/ED_sculpt.h
===================================================================
--- branches/soc-2009-yukishiro/source/blender/editors/include/ED_sculpt.h	2009-06-10 22:03:50 UTC (rev 20797)
+++ branches/soc-2009-yukishiro/source/blender/editors/include/ED_sculpt.h	2009-06-11 00:46:42 UTC (rev 20798)
@@ -42,4 +42,8 @@
 void undo_imagepaint_step(int step);
 void undo_imagepaint_clear(void);
 
+/* paint_light.c */
+void undo_lightpaint_step(struct bContext *C, int step);
+void undo_lightpaint_clear(void);
+
 #endif

Modified: branches/soc-2009-yukishiro/source/blender/editors/sculpt_paint/paint_light.c
===================================================================
--- branches/soc-2009-yukishiro/source/blender/editors/sculpt_paint/paint_light.c	2009-06-10 22:03:50 UTC (rev 20797)
+++ branches/soc-2009-yukishiro/source/blender/editors/sculpt_paint/paint_light.c	2009-06-11 00:46:42 UTC (rev 20798)
@@ -79,6 +79,7 @@
 
 #include "paint_intern.h"
 
+/******************* computation job ****************/
 typedef struct ShJob {
 	Scene *scene;
         View3D *v3d;
@@ -137,17 +138,116 @@
 
 }
 
-static int *get_indexarray(void)
+/*************************** undo and redo *********************************/
+
+typedef struct UndoCoeffs {
+	void *next, *prev;
+        float coeffs[25][3];
+} UndoCoeffs;
+
+static ListBase strokes;
+static ListBase undo_coeffs;
+static ListBase redo_coeffs;
+static init_coeffs[25][3];
+
+static void undo_lightpaint_push(Scene *scene)
 {
-	return MEM_mallocN(sizeof(int)*MAXINDEX + 2, "lightpaint");
+        int i, j;
+        LightEnv *env = get_scene_lightenv(scene);
+        UndoCoeffs *uc = MEM_callocN(sizeof(UndoCoeffs), "UndoCoeffs");
+
+        for (i = 0; i < 25; i++) {
+                for (j = 0; j < 3; j++) {
+                        uc->coeffs[i][j] = env->shcoeffs[i][j];
+                }
+        }
+
+        BLI_addtail(&undo_coeffs, uc);
+        BLI_freelistN(&redo_coeffs);
 }
 
-static unsigned int lpaint_get_current_col(VPaint *lp)
+static void undo_lightpaint_init(Scene *scene)
 {
-        // XXX: use vertex ABGR
-	return rgba_to_mcol(1.0f, lp->brush->rgb[2], lp->brush->rgb[1], lp->brush->rgb[0]);
+        int i, j;
+        LightEnv *env;
+
+        if (undo_coeffs.first == NULL) {
+                env = get_scene_lightenv(scene);
+                for (i = 0; i < 25; i++) {
+                        for (j = 0; j < 3; j++) {
+                                init_coeffs[i][j] = env->shcoeffs[i][j];
+                        }
+                }
+        }
 }
 
+void undo_lightpaint_step(bContext *C, int step)
+{
+        VPaint *lp = CTX_data_tool_settings(C)->lpaint;
+        RegionView3D *rv3d = CTX_wm_region_view3d(C);
+        Scene *scene = CTX_data_scene(C);
+        LightEnv *env = get_scene_lightenv(scene);
+        PaintStroke *ps;
+        UndoCoeffs *uc;
+        int i, j;
+
+        if (step == 1) {
+                ps = (PaintStroke*)lp->lpaint_data.last;
+                uc = (UndoCoeffs*)undo_coeffs.last;
+        
+                if (ps && uc) {
+                        BLI_remlink(&lp->lpaint_data, ps);
+                        BLI_addtail(&strokes, ps);
+
+                        BLI_remlink(&undo_coeffs, uc);
+                        BLI_addtail(&redo_coeffs, uc);
+                        uc = (UndoCoeffs*)undo_coeffs.last;
+
+                        if (uc != NULL) {
+                                for (i = 0; i < 25; i++) {
+                                        for (j = 0; j < 3; j++) {
+                                                env->shcoeffs[i][j] = uc->coeffs[i][j];
+                                        }
+                                }
+                        } else {
+                                for (i = 0; i < 25; i++) {
+                                        for (j = 0; j < 3; j++) {
+                                                env->shcoeffs[i][j] = init_coeffs[i][j];
+                                        }
+                                }
+                        }
+                } 
+
+        }
+        else if (step == -1) {
+                ps = (PaintStroke*)strokes.last;
+                uc = (UndoCoeffs*)redo_coeffs.last;
+        
+                if (ps && uc) {
+                        BLI_remlink(&strokes, ps);
+                        BLI_addtail(&lp->lpaint_data, ps);
+
+                        for (i = 0; i < 25; i++) {
+                                for (j = 0; j < 3; j++) {
+                                        env->shcoeffs[i][j] = uc->coeffs[i][j];
+                                }
+                        }
+                        BLI_remlink(&redo_coeffs, uc);
+                        BLI_addtail(&undo_coeffs, uc);
+                }
+        }
+
+        rv3d->rflag |= RV3D_RECALCMCOL;
+        ED_region_tag_redraw(CTX_wm_region(C));
+}
+
+
+void undo_lightpaint_clear(void)
+{
+        BLI_freelistN(&undo_coeffs);
+        BLI_freelistN(&redo_coeffs);
+}
+
 /************************ light paint poll ************************/
 static int light_paint_poll(bContext *C)
 {
@@ -177,7 +277,7 @@
 	return 1;
 }
 
-/* Cursor */
+/****************** cursor ******************/
 static void lp_drawcursor(bContext *C, int x, int y, void *customdata)
 {
 	ToolSettings *ts= CTX_data_tool_settings(C);
@@ -208,6 +308,8 @@
         }
 }
 
+/**************** light paint toggle **************/
+
 static VPaint *new_lpaint()
 {
 	VPaint *lp= MEM_callocN(sizeof(VPaint), "Light VPaint");
@@ -295,6 +397,17 @@
 	float vpimat[3][3];
 } PaintOperation;
 
+static int *get_indexarray(void)
+{
+	return MEM_mallocN(sizeof(int)*MAXINDEX + 2, "lightpaint");
+}
+
+static unsigned int lpaint_get_current_col(VPaint *lp)
+{
+        // XXX: use vertex ABGR
+	return rgba_to_mcol(1.0f, lp->brush->rgb[2], lp->brush->rgb[1], lp->brush->rgb[0]);
+}
+
 PaintStroke* create_stroke()
 {
         PaintStroke *ps;
@@ -342,10 +455,11 @@
 static void compute_color(Scene *scene, PaintStroke *ps)
 {
         PaintStroke *cur_ps = ps;
+        LightEnv *env;
         Mesh *me; 
         MShCoeffs *coeffs;
-        int totvert = 0, i, j, index;
-        int num_sh = 9; // (L+1) * (L+1)
+        int num_sh = 9, totvert = 0; // (L+1) * (L+1)
+        int iter = 1, i, j, k, index;
         float *I[3];
         float *P;
         float *C[3];
@@ -356,6 +470,12 @@
                 cur_ps = cur_ps->next;
         }
 
+        if (totvert == 0) return;
+        if (totvert < num_sh) {
+                iter = num_sh / totvert + 1;
+                totvert *= iter;
+        }
+
         // create arrays I, P, C
         // TODO: find a solver that can solve r, g, b at the same time
         P = MEM_callocN(sizeof(float) * totvert * num_sh, "P");
@@ -366,31 +486,32 @@
         C[1] = MEM_callocN(sizeof(float) * num_sh, "Cg");
         C[2] = MEM_callocN(sizeof(float) * num_sh, "Cb");
 
-        cur_ps = ps;
         index = 0;
-        while (cur_ps) {
-                me = get_mesh(cur_ps->ob);
-                coeffs= CustomData_get_layer(&me->vdata, CD_MSHCOEFFS);
+        for (k = 0; k < iter; k++) {
+                cur_ps = ps;
+                while (cur_ps) {
+                        me = get_mesh(cur_ps->ob);
+                        coeffs= CustomData_get_layer(&me->vdata, CD_MSHCOEFFS);
 
-                // set P, I
-                for (i = 0; i < cur_ps->size; i++) {
-                        for (j = 0; j < num_sh; j++) {
-                                P[index * num_sh + j] = coeffs[cur_ps->v_index[i]].val[j];
+                        // set P, I
+                        for (i = 0; i < cur_ps->size; i++) {
+                                for (j = 0; j < num_sh; j++) {
+                                        P[index * num_sh + j] = coeffs[cur_ps->v_index[i]].val[j];
+                                }
+                                I[0][index] = cur_ps->r;
+                                I[1][index] = cur_ps->g;
+                                I[2][index] = cur_ps->b;
+                                index++;
                         }
-                        I[0][index] = cur_ps->r;
-                        I[1][index] = cur_ps->g;
-                        I[2][index] = cur_ps->b;
-                        index++;
+                        cur_ps = cur_ps->next;
                 }
-
-                cur_ps = cur_ps->next;
         }
 
         // call solver
         SH_solve(P, I, totvert, num_sh, C);
 
         // get light coeffs
-        LightEnv* env = get_scene_lightenv(scene);
+        env = get_scene_lightenv(scene);
         for (i = 0; i < num_sh; i++) {
                 env->shcoeffs[i][0] = C[0][i];
                 env->shcoeffs[i][1] = C[1][i];
@@ -429,13 +550,13 @@
 		case LEFTMOUSE:
 			if(event->val==0) { /* release */
                                 PaintStroke *ps = (PaintStroke*)lp->lpaint_data.first;
-                                // call SH solver here
                                 compute_color(scene, ps);
+				lpaint_exit(C, op);
+                                undo_lightpaint_push(scene);
                                 // signal for recompute
-				lpaint_exit(C, op);
+                                vc->rv3d->rflag |= RV3D_RECALCMCOL;
+                                ED_region_tag_redraw(vc->ar);
 
-                                vc->rv3d->rflag |= RV3D_RECALCMCOL;
-			        ED_region_tag_redraw(vc->ar);
 				return OPERATOR_FINISHED;
 			}
 			/* pass on, first press gets painted too */
@@ -506,6 +627,8 @@
         ps->b = lp->brush->rgb[2];
         BLI_addtail(&lp->lpaint_data, ps);
 
+        undo_lightpaint_init(CTX_data_scene(C));
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list