[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22635] branches/blender2.5/blender/source /blender/editors: 2.5/Paint:

Nicholas Bishop nicholasbishop at gmail.com
Wed Aug 19 23:24:55 CEST 2009


Revision: 22635
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22635
Author:   nicholasbishop
Date:     2009-08-19 23:24:52 +0200 (Wed, 19 Aug 2009)

Log Message:
-----------
2.5/Paint:

* Some initial work on a new paint abstraction, PaintStroke. For now, most of the code just pulls out stroke-related stuff from sculpt mode, next step is to integrate the other paint modes to use this. It'll enable stuff like smooth stroke for all the paint modes with less code duplication.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/editors/include/ED_view3d.h
    branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_intern.h
    branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_vertex.c
    branches/blender2.5/blender/source/blender/editors/sculpt_paint/sculpt.c
    branches/blender2.5/blender/source/blender/editors/space_view3d/view3d_view.c

Added Paths:
-----------
    branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_stroke.c

Modified: branches/blender2.5/blender/source/blender/editors/include/ED_view3d.h
===================================================================
--- branches/blender2.5/blender/source/blender/editors/include/ED_view3d.h	2009-08-19 16:49:21 UTC (rev 22634)
+++ branches/blender2.5/blender/source/blender/editors/include/ED_view3d.h	2009-08-19 21:24:52 UTC (rev 22635)
@@ -70,6 +70,7 @@
 void initgrabz(struct RegionView3D *rv3d, float x, float y, float z);
 void window_to_3d(struct ARegion *ar, float *vec, short mx, short my);
 void window_to_3d_delta(struct ARegion *ar, float *vec, short mx, short my);
+void view3d_unproject(struct bglMats *mats, float out[3], const short x, const short y, const float z);
 
 /* Depth buffer */
 float read_cached_depth(struct ViewContext *vc, int x, int y);

Modified: branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_intern.h
===================================================================
--- branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_intern.h	2009-08-19 16:49:21 UTC (rev 22634)
+++ branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_intern.h	2009-08-19 21:24:52 UTC (rev 22635)
@@ -29,13 +29,28 @@
 #ifndef ED_PAINT_INTERN_H
 #define ED_PAINT_INTERN_H
 
+struct bContext;
 struct Scene;
 struct Object;
 struct Mesh;
+struct PaintStroke;
+struct PointerRNA;
 struct ViewContext;
+struct wmEvent;
+struct wmOperator;
 struct wmOperatorType;
 struct ARegion;
 
+/* paint_stroke.c */
+typedef int (*StrokeTestStart)(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+typedef void (*StrokeUpdateStep)(struct bContext *C, struct PaintStroke *stroke, struct PointerRNA *itemptr);
+typedef void (*StrokeDone)(struct bContext *C, struct PaintStroke *stroke);
+
+struct PaintStroke *paint_stroke_new(bContext *C, StrokeTestStart test_start,
+				     StrokeUpdateStep update_step, StrokeDone done);
+int paint_stroke_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke);
+
 /* paint_vertex.c */
 void PAINT_OT_weight_paint_toggle(struct wmOperatorType *ot);
 void PAINT_OT_weight_paint_radial_control(struct wmOperatorType *ot);

Added: branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_stroke.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_stroke.c	                        (rev 0)
+++ branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_stroke.c	2009-08-19 21:24:52 UTC (rev 22635)
@@ -0,0 +1,224 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software  Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 by Nicholas Bishop
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
+#include "RNA_access.h"
+
+#include "BKE_context.h"
+#include "BKE_paint.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BLI_arithb.h"
+
+#include "BIF_glutil.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "paint_intern.h"
+
+#include <float.h>
+#include <math.h>
+
+typedef struct PaintStroke {
+	/* Cached values */
+	ViewContext vc;
+	bglMats mats;
+	Brush *brush;
+
+	float last_mouse_position[2];
+
+	/* Set whether any stroke step has yet occured
+	   e.g. in sculpt mode, stroke doesn't start until cursor
+	   passes over the mesh */
+	int stroke_started;
+
+	StrokeTestStart test_start;
+	StrokeUpdateStep update_step;
+	StrokeDone done;
+} PaintStroke;
+
+/* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */
+static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse[2])
+{
+	PointerRNA itemptr;
+	float cur_depth, pressure = 1;
+	float center[3];
+	PaintStroke *stroke = op->customdata;
+
+	cur_depth = read_cached_depth(&stroke->vc, mouse[0], mouse[1]);
+	view3d_unproject(&stroke->mats, center, mouse[0], mouse[1], cur_depth);	
+
+	/* Tablet */
+	if(event->custom == EVT_DATA_TABLET) {
+		wmTabletData *wmtab= event->customdata;
+		if(wmtab->Active != EVT_TABLET_NONE)
+			pressure= wmtab->Pressure;
+	}
+				
+	/* Add to stroke */
+	RNA_collection_add(op->ptr, "stroke", &itemptr);
+	RNA_float_set_array(&itemptr, "location", center);
+	RNA_float_set_array(&itemptr, "mouse", mouse);
+	RNA_boolean_set(&itemptr, "flip", event->shift);
+	RNA_float_set(&itemptr, "pressure", pressure);
+
+	stroke->last_mouse_position[0] = mouse[0];
+	stroke->last_mouse_position[1] = mouse[1];
+
+	stroke->update_step(C, stroke, &itemptr);
+}
+
+/* Returns zero if no sculpt changes should be made, non-zero otherwise */
+static int paint_smooth_stroke(PaintStroke *stroke, float output[2], wmEvent *event)
+{
+	output[0] = event->x;
+	output[1] = event->y;
+
+	if(stroke->brush->flag & BRUSH_SMOOTH_STROKE && stroke->brush->sculpt_tool != SCULPT_TOOL_GRAB) {
+		float u = stroke->brush->smooth_stroke_factor, v = 1.0 - u;
+		float dx = stroke->last_mouse_position[0] - event->x, dy = stroke->last_mouse_position[1] - event->y;
+
+		/* If the mouse is moving within the radius of the last move,
+		   don't update the mouse position. This allows sharp turns. */
+		if(dx*dx + dy*dy < stroke->brush->smooth_stroke_radius * stroke->brush->smooth_stroke_radius)
+			return 0;
+
+		output[0] = event->x * v + stroke->last_mouse_position[0] * u;
+		output[1] = event->y * v + stroke->last_mouse_position[1] * u;
+	}
+
+	return 1;
+}
+
+/* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
+static int paint_space_stroke_enabled(Brush *br)
+{
+	return (br->flag & BRUSH_SPACE) && !(br->flag & BRUSH_ANCHORED) && (br->sculpt_tool != SCULPT_TOOL_GRAB);
+}
+
+/* For brushes with stroke spacing enabled, moves mouse in steps
+   towards the final mouse location. */
+static int paint_space_stroke(bContext *C, wmOperator *op, wmEvent *event, const float final_mouse[2])
+{
+	PaintStroke *stroke = op->customdata;
+	int cnt = 0;
+
+	if(paint_space_stroke_enabled(stroke->brush)) {
+		float mouse[2] = {stroke->last_mouse_position[0], stroke->last_mouse_position[1]};
+		float vec[2] = {final_mouse[0] - mouse[0], final_mouse[1] - mouse[1]};
+		float length, scale;
+		int steps = 0, i;
+
+		/* Normalize the vector between the last stroke dot and the goal */
+		length = sqrt(vec[0]*vec[0] + vec[1]*vec[1]);
+
+		if(length > FLT_EPSILON) {
+			scale = stroke->brush->spacing / length;
+			vec[0] *= scale;
+			vec[1] *= scale;
+
+			steps = (int)(length / stroke->brush->spacing);
+			for(i = 0; i < steps; ++i, ++cnt) {
+				mouse[0] += vec[0];
+				mouse[1] += vec[1];
+				paint_brush_stroke_add_step(C, op, event, mouse);
+			}
+		}
+	}
+
+	return cnt;
+}
+
+/**** Public API ****/
+
+PaintStroke *paint_stroke_new(bContext *C, StrokeTestStart test_start,
+			      StrokeUpdateStep update_step, StrokeDone done)
+{
+	PaintStroke *stroke = MEM_callocN(sizeof(PaintStroke), "PaintStroke");
+
+	stroke->brush = paint_brush(paint_get_active(CTX_data_scene(C)));
+	view3d_set_viewcontext(C, &stroke->vc);
+	view3d_get_transformation(&stroke->vc, stroke->vc.obact, &stroke->mats);
+
+	stroke->test_start = test_start;
+	stroke->update_step = update_step;
+	stroke->done = done;
+
+	return stroke;
+}
+
+int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+	ARegion *ar = CTX_wm_region(C);
+	PaintStroke *stroke = op->customdata;
+	float mouse[2];
+
+	if(!stroke->stroke_started) {
+		stroke->last_mouse_position[0] = event->x;
+		stroke->last_mouse_position[1] = event->y;
+		stroke->stroke_started = stroke->test_start(C, op, event);
+		ED_region_tag_redraw(ar);
+	}
+
+	if(stroke->stroke_started) {
+		if(paint_smooth_stroke(stroke, mouse, event)) {
+			if(paint_space_stroke_enabled(stroke->brush)) {
+				if(!paint_space_stroke(C, op, event, mouse))
+					ED_region_tag_redraw(ar);
+			}
+			else
+				paint_brush_stroke_add_step(C, op, event, mouse);
+		}
+		else
+			ED_region_tag_redraw(ar);
+	}
+
+	/* TODO: fix hardcoded event here */
+	if(event->type == LEFTMOUSE && event->val == 0) {
+		stroke->done(C, stroke);
+		MEM_freeN(stroke);
+		return OPERATOR_FINISHED;
+	}
+	else
+		return OPERATOR_RUNNING_MODAL;
+}
+
+ViewContext *paint_stroke_view_context(PaintStroke *stroke)
+{
+	return &stroke->vc;
+}
+

Modified: branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_vertex.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_vertex.c	2009-08-19 16:49:21 UTC (rev 22634)
+++ branches/blender2.5/blender/source/blender/editors/sculpt_paint/paint_vertex.c	2009-08-19 21:24:52 UTC (rev 22635)
@@ -1709,122 +1709,123 @@
 	op->customdata= NULL;
 }
 
-static int vpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
+static void vpaint_dot(bContext *C, struct VPaintData *vpd, wmEvent *event)
 {
 	ToolSettings *ts= CTX_data_tool_settings(C);
 	VPaint *vp= ts->vpaint;
 	Brush *brush = paint_brush(&vp->paint);
-	
-	switch(event->type) {
-		case LEFTMOUSE:
-			if(event->val==0) { /* release */
-				vpaint_exit(C, op);
-				return OPERATOR_FINISHED;
-			}
-			/* pass on, first press gets painted too */
+	ViewContext *vc= &vpd->vc;
+	Object *ob= vc->obact;
+	Mesh *me= ob->data;
+	float mat[4][4];
+	int *indexar= vpd->indexar;
+	int totindex, index;
+	short mval[2];
 			
-		case MOUSEMOVE: 
-		{
-			struct VPaintData *vpd= op->customdata;
-			ViewContext *vc= &vpd->vc;
-			Object *ob= vc->obact;
-			Mesh *me= ob->data;
-			float mat[4][4];

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list