[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29260] branches/soc-2010-jwilkins: == Surface Brush & Surface Size Lock ==

Jason Wilkins Jason.A.Wilkins at gmail.com
Sun Jun 6 03:31:38 CEST 2010


Revision: 29260
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29260
Author:   jwilkins
Date:     2010-06-06 03:31:37 +0200 (Sun, 06 Jun 2010)

Log Message:
-----------
== Surface Brush & Surface Size Lock ==
I now consider surface brush and size lock to be alpha quality now.  

* paint brush no longer shows when the model is not hit
* added slider for "surface size" and changed name of "lock brush size" to "Use Surface Size", also fixed issue with surface size only taking effect when you start to sculpt.
* checkbox to activate "draw brush on surface"
* temporary hack to get surface drawn brush to refresh, i force blender to redraw the screen when its on
* Fixing this hack will require that there be a way to tell the "triple" drawing path to save and restore the zbuffer
* if stencil buffer usage is a problem, then maybe it could be a global option
* temporary hack to get surface size and brush size to refresh in real time (just need to do more research on this one)
* Still to-do: drawing the smooth and anchor brushes on the surface correctly

Modified Paths:
--------------
    branches/soc-2010-jwilkins/release/scripts/ui/space_view3d_toolbar.py
    branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/paint_stroke.c
    branches/soc-2010-jwilkins/source/blender/makesrna/intern/rna_brush.c

Modified: branches/soc-2010-jwilkins/release/scripts/ui/space_view3d_toolbar.py
===================================================================
--- branches/soc-2010-jwilkins/release/scripts/ui/space_view3d_toolbar.py	2010-06-06 01:15:44 UTC (rev 29259)
+++ branches/soc-2010-jwilkins/release/scripts/ui/space_view3d_toolbar.py	2010-06-06 01:31:37 UTC (rev 29260)
@@ -547,15 +547,23 @@
             col.separator()
 
             row = col.row(align=True)
-            row.prop(brush, "lock_brush_size")
+            row.prop(brush, "lock_brush_size", text="Use Surface Size")
 
             row = col.row(align=True)
-            row.prop(brush, "size", slider=True)
+            row.prop(brush, "unprojected_radius", text="Surface Size", slider=True)
+            row.active = brush.lock_brush_size
+
+            if brush.sculpt_tool != 'GRAB' and brush.lock_brush_size:
+                row.prop(brush, "use_size_pressure", toggle=True, text="")
+
+            row = col.row(align=True)
+            row.prop(brush, "size", slider=True, text="Pixel Size")
             row.active = not brush.lock_brush_size
 
-            if brush.sculpt_tool != 'GRAB':
+            if brush.sculpt_tool != 'GRAB' and not brush.lock_brush_size:
                 row.prop(brush, "use_size_pressure", toggle=True, text="")
 
+            if brush.sculpt_tool != 'GRAB':
                 row = col.row(align=True)
                 row.prop(brush, "strength", slider=True)
                 row.prop(brush, "use_strength_pressure", text="")

Modified: branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/paint_stroke.c
===================================================================
--- branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/paint_stroke.c	2010-06-06 01:15:44 UTC (rev 29259)
+++ branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/paint_stroke.c	2010-06-06 01:31:37 UTC (rev 29260)
@@ -160,22 +160,45 @@
 
 	size= RNA_struct_find_property(&brushptr, "size");
 	RNA_property_int_set(&brushptr, size, value);
+
+	// XXX This is a hack to redraw the control until I find out how to just redraw one control
+	WM_main_add_notifier(NC_OBJECT|ND_DRAW, NULL);
 }
 
-static int sculpt_get_brush_geometry(bContext* C, int mouse[2], int* pixel_radius, float location[3], float modelview[16], float projection[16], int viewport[4])
+static void sculpt_set_brush_unprojected_radius(Brush *brush, float value)
 {
+	PointerRNA brushptr;
+	PropertyRNA *unprojected_radius;
+
+	/* brush.unprojected_radius = value */
+
+	RNA_id_pointer_create(&brush->id, &brushptr);
+
+	unprojected_radius= RNA_struct_find_property(&brushptr, "unprojected_radius");
+	RNA_property_float_set(&brushptr, unprojected_radius, value);
+
+	// XXX This is a hack to redraw the control until I find out how to just redraw one control
+	WM_main_add_notifier(NC_OBJECT|ND_DRAW, NULL);
+}
+
+static int sculpt_get_brush_geometry(bContext* C, int x, int y, int* pixel_radius, float location[3], float modelview[16], float projection[16], int viewport[4])
+{
 	struct PaintStroke *stroke;
 	float window[2];
 	int hit;
 
 	stroke = paint_stroke_new(C, NULL, NULL, NULL, NULL);
 
-	window[0] = mouse[0] + stroke->vc.ar->winrct.xmin;
-	window[1] = mouse[1] + stroke->vc.ar->winrct.ymin;
+	window[0] = x + stroke->vc.ar->winrct.xmin;
+	window[1] = y + stroke->vc.ar->winrct.ymin;
 
 	if (stroke->vc.obact->sculpt->pbvh && sculpt_stroke_get_location(C, stroke, location, window)) {
 		*pixel_radius = project_brush_radius(stroke->vc.rv3d, stroke->brush->unprojected_radius, location, &stroke->mats);
 
+		if (*pixel_radius == 0) {
+			*pixel_radius = stroke->brush->size;
+		}
+
 		mul_m4_v3(stroke->vc.obact->sculpt->ob->obmat, location);
 
 		memcpy(modelview, stroke->vc.rv3d->viewmat, sizeof(float[16]));
@@ -214,94 +237,114 @@
 
 static void paint_draw_cursor(bContext *C, int x, int y, void *customdata)
 {
-	int mouse[3] = { x, y };
 	Paint *paint = paint_get_active(CTX_data_scene(C));
 	Brush *brush = paint_brush(paint);
-	GLUquadric* sphere;
-	int pixel_radius;
-	float location[3];
-	float modelview[16], projection[16];
-	int viewport[4];
+
+	int pixel_radius, viewport[4];
+	float location[3], modelview[16], projection[16];
+
 	int hit;
 
-	if(!(paint->flags & PAINT_SHOW_BRUSH)) return;
+	if(!(brush->flag & BRUSH_LOCK_SIZE) && !(paint->flags & PAINT_SHOW_BRUSH)) 
+		return;
 
-	glColor4ubv(paint_get_active(CTX_data_scene(C))->paint_cursor_col);
-	glEnable(GL_BLEND);
+	hit = sculpt_get_brush_geometry(C, x, y, &pixel_radius, location, modelview, projection, viewport);
 
-	hit = sculpt_get_brush_geometry(C, mouse, &pixel_radius, location, modelview, projection, viewport);
-
 	if (brush->flag & BRUSH_LOCK_SIZE) sculpt_set_brush_radius(brush, pixel_radius);
 
-	if (paint->flags & PAINT_SHOW_BRUSH_ON_SURFACE && hit) {
-		float size;
+	if (hit) {
 		ViewContext vc;
+		float unprojected_radius;
+
 		view3d_set_viewcontext(C, &vc);
 
-		glMatrixMode(GL_MODELVIEW);
-		glPushMatrix();
-		glLoadMatrixf(modelview);
-		glTranslatef(location[0], location[1], location[2]);
+		unprojected_radius = unproject_brush_radius(CTX_data_active_object(C), &vc, location, brush->size);
 
-		glMatrixMode(GL_PROJECTION);
-		glPushMatrix();
-		glLoadMatrixf(projection);
+		if (!(brush->flag & BRUSH_LOCK_SIZE)) 
+			sculpt_set_brush_unprojected_radius(brush, unprojected_radius);
 
-		glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
+		if(!(paint->flags & PAINT_SHOW_BRUSH)) return;
 
-		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-		glDepthMask(GL_FALSE);
+		glColor4ubv(paint_get_active(CTX_data_scene(C))->paint_cursor_col);
+		glEnable(GL_BLEND);
 
-		glDisable(GL_CULL_FACE);
+		if (paint->flags & PAINT_SHOW_BRUSH_ON_SURFACE) {
+			GLUquadric* sphere;
 
-		glEnable(GL_DEPTH_TEST);
+			glMatrixMode(GL_MODELVIEW);
+			glPushMatrix();
+			glLoadMatrixf(modelview);
+			glTranslatef(location[0], location[1], location[2]);
 
-		glClearStencil(0);
-		glClear(GL_STENCIL_BUFFER_BIT);
-		glEnable(GL_STENCIL_TEST);
+			glMatrixMode(GL_PROJECTION);
+			glPushMatrix();
+			glLoadMatrixf(projection);
 
-		glStencilFunc(GL_ALWAYS, 1, 1);
-		glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
+			glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
 
-		size = unproject_brush_radius(CTX_data_active_object(C), &vc, location, brush->size);
+			glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+			glDepthMask(GL_FALSE);
 
-		sphere = gluNewQuadric();
-		gluSphere(sphere, size, 40, 40);
+			glDisable(GL_CULL_FACE);
 
-		glStencilFunc(GL_ALWAYS, 0, 1);
-		glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
+			glEnable(GL_DEPTH_TEST);
 
-		gluSphere(sphere, size * 0.8f, 40, 40);
+			glClearStencil(0);
+			glClear(GL_STENCIL_BUFFER_BIT);
+			glEnable(GL_STENCIL_TEST);
 
-		glStencilFunc(GL_EQUAL, 1, 1);
+			glStencilFunc(GL_ALWAYS, 3, 0xFF);
+			glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
 
-		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+			sphere = gluNewQuadric();
 
-		gluSphere(sphere, size, 40, 40);
-		gluDeleteQuadric(sphere);
+			gluSphere(sphere, unprojected_radius, 40, 40);
 
-		glDisable(GL_DEPTH_TEST);
+			glStencilFunc(GL_ALWAYS, 1, 0xFF);
+			glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
 
-		glEnable(GL_CULL_FACE);
+			gluSphere(sphere, unprojected_radius * 0.8f, 40, 40);
 
-		glDisable(GL_STENCIL_TEST);
+			glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 
-		glDepthMask(GL_TRUE);
+			glStencilFunc(GL_EQUAL, 1, 0xFF);
+			glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
 
-		glPopMatrix();
+			gluSphere(sphere, unprojected_radius, 40, 40);
 
-		glMatrixMode(GL_MODELVIEW);
-		glPopMatrix();
+			glStencilFunc(GL_EQUAL, 3, 0xFF);
+			glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+			gluSphere(sphere, unprojected_radius, 40, 40);
+
+			gluDeleteQuadric(sphere);
+
+			glDisable(GL_DEPTH_TEST);
+
+			glEnable(GL_CULL_FACE);
+
+			glDisable(GL_STENCIL_TEST);
+
+			glDepthMask(GL_TRUE);
+
+			glPopMatrix();
+
+			glMatrixMode(GL_MODELVIEW);
+			glPopMatrix();
+
+			// XXX This is a hack to redraw the screen so that the zbuffer is recreated
+			WM_main_add_notifier(NC_OBJECT|ND_DRAW, NULL);
+		}
+		else {
+			glEnable(GL_LINE_SMOOTH);
+			glTranslatef((float)x, (float)y, 0.0f);
+			glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40);
+			glTranslatef((float)-x, (float)-y, 0.0f);
+			glDisable(GL_LINE_SMOOTH);
+		}
+
+		glDisable(GL_BLEND);
 	}
-	else {
-		glEnable(GL_LINE_SMOOTH);
-		glTranslatef((float)x, (float)y, 0.0f);
-		glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40);
-		glTranslatef((float)-x, (float)-y, 0.0f);
-		glDisable(GL_LINE_SMOOTH);
-	}
-
-	glDisable(GL_BLEND);
 }
 
 /* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */

Modified: branches/soc-2010-jwilkins/source/blender/makesrna/intern/rna_brush.c
===================================================================
--- branches/soc-2010-jwilkins/source/blender/makesrna/intern/rna_brush.c	2010-06-06 01:15:44 UTC (rev 29259)
+++ branches/soc-2010-jwilkins/source/blender/makesrna/intern/rna_brush.c	2010-06-06 01:31:37 UTC (rev 29260)
@@ -198,9 +198,10 @@
 	RNA_def_property_ui_text(prop, "Size", "Radius of the brush");
 	RNA_def_property_update(prop, 0, "rna_Brush_update");
 	
-	prop= RNA_def_property(srna, "unprojected_radius", PROP_INT, PROP_NONE);
+	prop= RNA_def_property(srna, "unprojected_radius", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_range(prop, 0, FLT_MAX);
-	RNA_def_property_ui_text(prop, "Unprojected Radius", "Radius of brush in Blender units");
+	RNA_def_property_ui_range(prop, 0, 1, 0, 0);
+	RNA_def_property_ui_text(prop, "Surface Size", "Radius of brush in Blender units");
 	RNA_def_property_update(prop, 0, "rna_Brush_update");
 
 	prop= RNA_def_property(srna, "detail", PROP_FLOAT, PROP_NONE);





More information about the Bf-blender-cvs mailing list