[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25651] trunk/blender/source/blender: - grease pencil mode for drawing onto geometry (using the z-buffer), access in the 3D view panel.

Campbell Barton ideasman42 at gmail.com
Fri Jan 1 16:05:34 CET 2010


Revision: 25651
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25651
Author:   campbellbarton
Date:     2010-01-01 16:05:31 +0100 (Fri, 01 Jan 2010)

Log Message:
-----------
- grease pencil mode for drawing onto geometry (using the z-buffer), access in the 3D view panel.
- account for parts of the line going off into infinity by making the stroke stretch between the last valid depth values (like an elastic band), if the endpoints are not over any geometry then use the closest valid depth.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/gpencil/gpencil_buttons.c
    trunk/blender/source/blender/editors/gpencil/gpencil_paint.c
    trunk/blender/source/blender/editors/include/ED_view3d.h
    trunk/blender/source/blender/editors/space_view3d/view3d_edit.c
    trunk/blender/source/blender/makesdna/DNA_gpencil_types.h
    trunk/blender/source/blender/makesrna/intern/rna_gpencil.c

Modified: trunk/blender/source/blender/editors/gpencil/gpencil_buttons.c
===================================================================
--- trunk/blender/source/blender/editors/gpencil/gpencil_buttons.c	2010-01-01 14:18:43 UTC (rev 25650)
+++ trunk/blender/source/blender/editors/gpencil/gpencil_buttons.c	2010-01-01 15:05:31 UTC (rev 25651)
@@ -229,7 +229,7 @@
 {
 	PointerRNA gpd_ptr;
 	bGPDlayer *gpl;
-	uiLayout *col;
+	uiLayout *col, *row;
 	
 	/* make new PointerRNA for Grease Pencil block */
 	RNA_id_pointer_create((ID *)gpd, &gpd_ptr);
@@ -259,7 +259,11 @@
 		uiItemL(col, "Drawing Settings:", 0);
 		
 		/* 'stick to view' option */
-		uiItemR(col, NULL, 0, &gpd_ptr, "view_space_draw", 0);
+		//uiItemR(col, NULL, 0, &gpd_ptr, "draw_mode", 0);
+		row= uiLayoutRow(layout, 1);
+		uiItemEnumR_string(row, NULL, 0, &gpd_ptr, "draw_mode", "VIEW");
+		uiItemEnumR_string(row, NULL, 0, &gpd_ptr, "draw_mode", "CURSOR");
+		uiItemEnumR_string(row, NULL, 0, &gpd_ptr, "draw_mode", "DEPTH");
 }	
 
 

Modified: trunk/blender/source/blender/editors/gpencil/gpencil_paint.c
===================================================================
--- trunk/blender/source/blender/editors/gpencil/gpencil_paint.c	2010-01-01 14:18:43 UTC (rev 25650)
+++ trunk/blender/source/blender/editors/gpencil/gpencil_paint.c	2010-01-01 15:05:31 UTC (rev 25651)
@@ -155,15 +155,7 @@
 static int gpencil_project_check (tGPsdata *p)
 {
 	bGPdata *gpd= p->gpd;
-	
-	if(	(gpd->sbuffer_sflag & GP_STROKE_3DSPACE) &&
-		(p->scene->toolsettings->snap_mode==SCE_SNAP_MODE_FACE) &&
-		(p->scene->toolsettings->snap_flag & SCE_SNAP_PROJECT) )
-	{
-		return 1;
-	}
-
-	return 0;
+	return ((gpd->sbuffer_sflag & GP_STROKE_3DSPACE) && (p->gpd->flag & GP_DATA_VIEWDEPTH)) ? 1:0;
 }
 
 /* ******************************************* */
@@ -220,13 +212,13 @@
 
 /* convert screen-coordinates to buffer-coordinates */
 // XXX this method needs a total overhaul!
-static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[])
+static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[], float *depth)
 {
 	bGPdata *gpd= p->gpd;
 	
 	/* in 3d-space - pt->x/y/z are 3 side-by-side floats */
 	if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) {
-		if(gpencil_project_check(p) && (view_autodist_simple(p->ar, mval, out))) {
+		if(gpencil_project_check(p) && (view_autodist_simple(p->ar, mval, out, depth))) {
 			/* projecting onto 3D-Geometry
 			 *	- nothing more needs to be done here, since view_autodist_simple() has already done it
 			 */
@@ -501,7 +493,7 @@
 			ptc= gpd->sbuffer;
 			
 			/* convert screen-coordinates to appropriate coordinates (and store them) */
-			gp_stroke_convertcoords(p, &ptc->x, &pt->x);
+			gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
 			
 			/* copy pressure */
 			pt->pressure= ptc->pressure;
@@ -514,23 +506,107 @@
 			ptc= ((tGPspoint *)gpd->sbuffer) + (gpd->sbuffer_size - 1);
 			
 			/* convert screen-coordinates to appropriate coordinates (and store them) */
-			gp_stroke_convertcoords(p, &ptc->x, &pt->x);
+			gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
 			
 			/* copy pressure */
 			pt->pressure= ptc->pressure;
 		}
 	}
 	else {
+		float *depth_arr= NULL;
+
+		/* get an array of depths, far depths are blended */
+		if(gpencil_project_check(p)) {
+			short mval[2];
+			int interp_depth = 0;
+			int found_depth = 0;
+
+			depth_arr= MEM_mallocN(sizeof(float) * gpd->sbuffer_size, "depth_points");
+
+			for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size; i++, ptc++, pt++) {
+				mval[0]= ptc->x; mval[1]= ptc->y;
+				if(view_autodist_depth(p->ar, mval, depth_arr+i) == 0)
+					interp_depth= TRUE;
+				else
+					found_depth= TRUE;
+			}
+
+			if(found_depth==FALSE) {
+				/* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */
+				for (i=gpd->sbuffer_size-1; i >= 0; i--)
+					depth_arr[i] = 0.9999f;
+			}
+			else if(interp_depth) {
+				/* found invalid depths, interpolate */
+				float valid_last= FLT_MAX;
+				int valid_ofs= 0;
+
+				float *depth_arr_up= MEM_callocN(sizeof(float) * gpd->sbuffer_size, "depth_points_up");
+				float *depth_arr_down= MEM_callocN(sizeof(float) * gpd->sbuffer_size, "depth_points_down");
+
+				int *depth_tot_up= MEM_callocN(sizeof(int) * gpd->sbuffer_size, "depth_tot_up");
+				int *depth_tot_down= MEM_callocN(sizeof(int) * gpd->sbuffer_size, "depth_tot_down");
+
+				for (i=0; i < gpd->sbuffer_size; i++) {
+					if(depth_arr[i] == FLT_MAX) {
+						depth_arr_up[i]= valid_last;
+						depth_tot_up[i]= ++valid_ofs;
+					}
+					else {
+						valid_last= depth_arr[i];
+						valid_ofs= 0;
+					}
+				}
+
+				valid_last= FLT_MAX;
+				valid_ofs= 0;
+
+				for (i=gpd->sbuffer_size-1; i >= 0; i--) {
+					if(depth_arr[i] == FLT_MAX) {
+						depth_arr_down[i]= valid_last;
+						depth_tot_down[i]= ++valid_ofs;
+					}
+					else {
+						valid_last= depth_arr[i];
+						valid_ofs= 0;
+					}
+				}
+
+				/* now blend */
+				for (i=0; i < gpd->sbuffer_size; i++) {
+					if(depth_arr[i] == FLT_MAX) {
+						if(depth_arr_up[i] != FLT_MAX && depth_arr_down[i] != FLT_MAX) {
+							depth_arr[i]= ((depth_arr_up[i] * depth_tot_down[i]) +  (depth_arr_down[i] * depth_tot_up[i])) / (float)(depth_tot_down[i] + depth_tot_up[i]);
+						} else if (depth_arr_up[i] != FLT_MAX) {
+							depth_arr[i]= depth_arr_up[i];
+						} else if (depth_arr_down[i] != FLT_MAX) {
+							depth_arr[i]= depth_arr_down[i];
+						}
+					}
+				}
+
+				MEM_freeN(depth_arr_up);
+				MEM_freeN(depth_arr_down);
+
+				MEM_freeN(depth_tot_up);
+				MEM_freeN(depth_tot_down);
+			}
+		}
+
+
+		pt= gps->points;
+
 		/* convert all points (normal behaviour) */
-		for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++) {
+		for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++, pt++) {
 			/* convert screen-coordinates to appropriate coordinates (and store them) */
-			gp_stroke_convertcoords(p, &ptc->x, &pt->x);
+			gp_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr+i:NULL);
 			
 			/* copy pressure */
 			pt->pressure= ptc->pressure;
-			
-			pt++;
 		}
+
+		if(depth_arr)
+			MEM_freeN(depth_arr);
 	}
 	
 	/* add stroke to frame */

Modified: trunk/blender/source/blender/editors/include/ED_view3d.h
===================================================================
--- trunk/blender/source/blender/editors/include/ED_view3d.h	2010-01-01 14:18:43 UTC (rev 25650)
+++ trunk/blender/source/blender/editors/include/ED_view3d.h	2010-01-01 15:05:31 UTC (rev 25651)
@@ -128,7 +128,8 @@
 
 /* only draw so view_autodist_simple can be called many times after */
 int view_autodist_init(struct Scene *scene, struct ARegion *ar, struct View3D *v3d);
-int view_autodist_simple(struct ARegion *ar, short *mval, float mouse_worldloc[3]);
+int view_autodist_simple(struct ARegion *ar, short *mval, float mouse_worldloc[3], float *force_depth);
+int view_autodist_depth(struct ARegion *ar, short *mval, float *depth);
 
 /* select */
 #define MAXPICKBUF      10000

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_edit.c	2010-01-01 14:18:43 UTC (rev 25650)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_edit.c	2010-01-01 15:05:31 UTC (rev 25651)
@@ -2282,7 +2282,7 @@
 }
 
 // no 4x4 sampling, run view_autodist_init first
-int view_autodist_simple(ARegion *ar, short *mval, float mouse_worldloc[3] ) //, float *autodist )
+int view_autodist_simple(ARegion *ar, short *mval, float mouse_worldloc[3], float *force_depth) //, float *autodist )
 {
 	RegionView3D *rv3d= ar->regiondata;
 	bglMats mats; /* ZBuffer depth vars, could cache? */
@@ -2295,15 +2295,18 @@
 	if (mval[1] >= rv3d->depths->h) return 0;
 
 	/* Get Z Depths, needed for perspective, nice for ortho */
-	bgl_get_mats(&mats);
-	depth= rv3d->depths->depths[mval[1]*rv3d->depths->w+mval[0]];
+	if(force_depth)
+		depth= *force_depth;
+	else
+		depth= rv3d->depths->depths[mval[1]*rv3d->depths->w+mval[0]];
 
-	if (depth==MAXFLOAT)
+	if (depth==FLT_MAX)
 		return 0;
 
 	cent[0] = (double)mval[0];
 	cent[1] = (double)mval[1];
 
+	bgl_get_mats(&mats);
 	if (!gluUnProject(cent[0], cent[1], depth, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
 		return 0;
 
@@ -2313,6 +2316,29 @@
 	return 1;
 }
 
+int view_autodist_depth(struct ARegion *ar, short *mval, float *depth)
+{
+	RegionView3D *rv3d= ar->regiondata;
+	*depth= FLT_MAX;
+
+	if (mval[0] < 0) return 0;
+	if (mval[1] < 0) return 0;
+	if (mval[0] >= rv3d->depths->w) return 0;
+	if (mval[1] >= rv3d->depths->h) return 0;
+
+	/* Get Z Depths, needed for perspective, nice for ortho */
+	*depth= rv3d->depths->depths[mval[1]*rv3d->depths->w+mval[0]];
+
+	/* float error means we need to shave off some */
+
+	if(*depth >= 1.0) {
+		*depth= FLT_MAX;
+	}
+
+	return (*depth==FLT_MAX) ? 0:1;
+		return 0;
+}
+
 /* ********************* NDOF ************************ */
 /* note: this code is confusing and unclear... (ton) */
 /* **************************************************** */

Modified: trunk/blender/source/blender/makesdna/DNA_gpencil_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_gpencil_types.h	2010-01-01 14:18:43 UTC (rev 25650)
+++ trunk/blender/source/blender/makesdna/DNA_gpencil_types.h	2010-01-01 15:05:31 UTC (rev 25651)
@@ -146,5 +146,7 @@
 #define GP_DATA_EDITPAINT	(1<<3)
 	/* new strokes are added in viewport space */
 #define GP_DATA_VIEWALIGN	(1<<4)
+	/* Project into the screens Z values */
+#define GP_DATA_VIEWDEPTH	(1<<5)
 
 #endif /*  DNA_GPENCIL_TYPES_H */

Modified: trunk/blender/source/blender/makesrna/intern/rna_gpencil.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_gpencil.c	2010-01-01 14:18:43 UTC (rev 25650)
+++ trunk/blender/source/blender/makesrna/intern/rna_gpencil.c	2010-01-01 15:05:31 UTC (rev 25651)
@@ -220,6 +220,12 @@
 	StructRNA *srna;
 	PropertyRNA *prop;
 	
+	static EnumPropertyItem draw_mode_items[] = {
+		{GP_DATA_VIEWALIGN, "CURSOR", 0, "Cursor", ""},
+		{0, "VIEW", 0, "View", ""}, /* weired, GP_DATA_VIEWALIGN is inverted */
+		{GP_DATA_VIEWALIGN|GP_DATA_VIEWDEPTH, "DEPTH", 0, "Depth", ""},
+		{0, NULL, 0, NULL, NULL}};
+
 	srna= RNA_def_struct(brna, "GreasePencil", "ID");
 	RNA_def_struct_sdna(srna, "bGPdata");

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list