[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [43512] trunk/blender/source/blender/ editors/sculpt_paint: Move paint's WM paint cursor code into a new file.

Nicholas Bishop nicholasbishop at gmail.com
Thu Jan 19 03:06:15 CET 2012


Revision: 43512
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43512
Author:   nicholasbishop
Date:     2012-01-19 02:06:09 +0000 (Thu, 19 Jan 2012)
Log Message:
-----------
Move paint's WM paint cursor code into a new file.

The paint cursor code is fairly muddled still and needs futher cleanup
(commented in the new file.) Over half the paint_stroke code was just
called from the cursor draw function.

There should be no functional changes from this.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/sculpt_paint/CMakeLists.txt
    trunk/blender/source/blender/editors/sculpt_paint/paint_stroke.c
    trunk/blender/source/blender/editors/sculpt_paint/sculpt.c

Added Paths:
-----------
    trunk/blender/source/blender/editors/sculpt_paint/paint_cursor.c

Modified: trunk/blender/source/blender/editors/sculpt_paint/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/CMakeLists.txt	2012-01-19 00:18:25 UTC (rev 43511)
+++ trunk/blender/source/blender/editors/sculpt_paint/CMakeLists.txt	2012-01-19 02:06:09 UTC (rev 43512)
@@ -38,6 +38,7 @@
 )
 
 set(SRC
+	paint_cursor.c
 	paint_image.c
 	paint_ops.c
 	paint_stroke.c

Copied: trunk/blender/source/blender/editors/sculpt_paint/paint_cursor.c (from rev 43500, trunk/blender/source/blender/editors/sculpt_paint/paint_stroke.c)
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_cursor.c	                        (rev 0)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_cursor.c	2012-01-19 02:06:09 UTC (rev 43512)
@@ -0,0 +1,623 @@
+/*
+ * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 by Nicholas Bishop
+ * All rights reserved.
+ *
+ * Contributor(s): Jason Wilkins, Tom Musgrove.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/editors/sculpt_paint/paint_cursor.c
+ *  \ingroup edsculpt
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_color_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
+
+#include "BKE_brush.h"
+#include "BKE_context.h"
+#include "BKE_paint.h"
+
+#include "WM_api.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "ED_view3d.h"
+
+#include "paint_intern.h"
+/* still needed for sculpt_stroke_get_location, should be
+   removed eventually (TODO) */
+#include "sculpt_intern.h"
+
+/* TODOs:
+
+   Some of the cursor drawing code is doing non-draw stuff
+   (e.g. updating the brush rake angle). This should be cleaned up
+   still.
+
+   There is also some ugliness with sculpt-specific code.
+ */
+
+typedef struct Snapshot {
+	float size[3];
+	float ofs[3];
+	float rot;
+	int brush_size;
+	int winx;
+	int winy;
+	int brush_map_mode;
+	int curve_changed_timestamp;
+} Snapshot;
+
+static int same_snap(Snapshot* snap, Brush* brush, ViewContext* vc)
+{
+	MTex* mtex = &brush->mtex;
+
+	return (((mtex->tex) &&
+			 equals_v3v3(mtex->ofs, snap->ofs) &&
+			 equals_v3v3(mtex->size, snap->size) &&
+			 mtex->rot == snap->rot) &&
+
+			/* make brush smaller shouldn't cause a resample */
+			((mtex->brush_map_mode == MTEX_MAP_MODE_FIXED &&
+			  (brush_size(vc->scene, brush) <= snap->brush_size)) ||
+			 (brush_size(vc->scene, brush) == snap->brush_size)) &&
+
+			(mtex->brush_map_mode == snap->brush_map_mode) &&
+			(vc->ar->winx == snap->winx) &&
+			(vc->ar->winy == snap->winy));
+}
+
+static void make_snap(Snapshot* snap, Brush* brush, ViewContext* vc)
+{
+	if (brush->mtex.tex) {
+		snap->brush_map_mode = brush->mtex.brush_map_mode;
+		copy_v3_v3(snap->ofs, brush->mtex.ofs);
+		copy_v3_v3(snap->size, brush->mtex.size);
+		snap->rot = brush->mtex.rot;
+	}
+	else {
+		snap->brush_map_mode = -1;
+		snap->ofs[0]= snap->ofs[1]= snap->ofs[2]= -1;
+		snap->size[0]= snap->size[1]= snap->size[2]= -1;
+		snap->rot = -1;
+	}
+
+	snap->brush_size = brush_size(vc->scene, brush);
+	snap->winx = vc->ar->winx;
+	snap->winy = vc->ar->winy;
+}
+
+static int load_tex(Sculpt *sd, Brush* br, ViewContext* vc)
+{
+	static GLuint overlay_texture = 0;
+	static int init = 0;
+	static int tex_changed_timestamp = -1;
+	static int curve_changed_timestamp = -1;
+	static Snapshot snap;
+	static int old_size = -1;
+
+	GLubyte* buffer = NULL;
+
+	int size;
+	int j;
+	int refresh;
+
+#ifndef _OPENMP
+	(void)sd; /* quied unused warning */
+#endif
+	
+	if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED && !br->mtex.tex) return 0;
+	
+	refresh = 
+		!overlay_texture ||
+		(br->mtex.tex && 
+		    (!br->mtex.tex->preview ||
+		      br->mtex.tex->preview->changed_timestamp[0] != tex_changed_timestamp)) ||
+		!br->curve ||
+		br->curve->changed_timestamp != curve_changed_timestamp ||
+		!same_snap(&snap, br, vc);
+
+	if (refresh) {
+		if (br->mtex.tex && br->mtex.tex->preview)
+			tex_changed_timestamp = br->mtex.tex->preview->changed_timestamp[0];
+
+		if (br->curve)
+			curve_changed_timestamp = br->curve->changed_timestamp;
+
+		make_snap(&snap, br, vc);
+
+		if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
+			int s = brush_size(vc->scene, br);
+			int r = 1;
+
+			for (s >>= 1; s > 0; s >>= 1)
+				r++;
+
+			size = (1<<r);
+
+			if (size < 256)
+				size = 256;
+
+			if (size < old_size)
+				size = old_size;
+		}
+		else
+			size = 512;
+
+		if (old_size != size) {
+			if (overlay_texture) {
+				glDeleteTextures(1, &overlay_texture);
+				overlay_texture = 0;
+			}
+
+			init = 0;
+
+			old_size = size;
+		}
+
+		buffer = MEM_mallocN(sizeof(GLubyte)*size*size, "load_tex");
+
+		#pragma omp parallel for schedule(static) if (sd->flags & SCULPT_USE_OPENMP)
+		for (j= 0; j < size; j++) {
+			int i;
+			float y;
+			float len;
+
+			for (i= 0; i < size; i++) {
+
+				// largely duplicated from tex_strength
+
+				const float rotation = -br->mtex.rot;
+				float radius = brush_size(vc->scene, br);
+				int index = j*size + i;
+				float x;
+				float avg;
+
+				x = (float)i/size;
+				y = (float)j/size;
+
+				x -= 0.5f;
+				y -= 0.5f;
+
+				if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) {
+					x *= vc->ar->winx / radius;
+					y *= vc->ar->winy / radius;
+				}
+				else {
+					x *= 2;
+					y *= 2;
+				}
+
+				len = sqrtf(x*x + y*y);
+
+				if ((br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) || len <= 1) {
+					/* it is probably worth optimizing for those cases where 
+					   the texture is not rotated by skipping the calls to
+					   atan2, sqrtf, sin, and cos. */
+					if (br->mtex.tex && (rotation > 0.001f || rotation < -0.001f)) {
+						const float angle    = atan2f(y, x) + rotation;
+
+						x = len * cosf(angle);
+						y = len * sinf(angle);
+					}
+
+					x *= br->mtex.size[0];
+					y *= br->mtex.size[1];
+
+					x += br->mtex.ofs[0];
+					y += br->mtex.ofs[1];
+
+					avg = br->mtex.tex ? paint_get_tex_pixel(br, x, y) : 1;
+
+					avg += br->texture_sample_bias;
+
+					if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED)
+						avg *= brush_curve_strength(br, len, 1); /* Falloff curve */
+
+					buffer[index] = 255 - (GLubyte)(255*avg);
+				}
+				else {
+					buffer[index] = 0;
+				}
+			}
+		}
+
+		if (!overlay_texture)
+			glGenTextures(1, &overlay_texture);
+	}
+	else {
+		size= old_size;
+	}
+
+	glBindTexture(GL_TEXTURE_2D, overlay_texture);
+
+	if (refresh) {
+		if (!init) {
+			glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
+			init = 1;
+		}
+		else {
+			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
+		}
+
+		if (buffer)
+			MEM_freeN(buffer);
+	}
+
+	glEnable(GL_TEXTURE_2D);
+
+	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+	if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+	}
+
+	return 1;
+}
+
+static int project_brush_radius(ViewContext *vc,
+								float radius,
+								const float location[3])
+{
+	float view[3], nonortho[3], ortho[3], offset[3], p1[2], p2[2];
+
+	ED_view3d_global_to_vector(vc->rv3d, location, view);
+
+	// create a vector that is not orthogonal to view
+
+	if (fabsf(view[0]) < 0.1f) {
+		nonortho[0] = view[0] + 1.0f;
+		nonortho[1] = view[1];
+		nonortho[2] = view[2];
+	}
+	else if (fabsf(view[1]) < 0.1f) {
+		nonortho[0] = view[0];
+		nonortho[1] = view[1] + 1.0f;
+		nonortho[2] = view[2];
+	}
+	else {
+		nonortho[0] = view[0];
+		nonortho[1] = view[1];
+		nonortho[2] = view[2] + 1.0f;
+	}
+
+	// get a vector in the plane of the view
+	cross_v3_v3v3(ortho, nonortho, view);
+	normalize_v3(ortho);
+
+	// make a point on the surface of the brush tagent to the view
+	mul_v3_fl(ortho, radius);
+	add_v3_v3v3(offset, location, ortho);
+
+	// project the center of the brush, and the tangent point to the view onto the screen
+	project_float(vc->ar, location, p1);
+	project_float(vc->ar, offset, p2);
+
+	// the distance between these points is the size of the projected brush in pixels
+	return len_v2v2(p1, p2);
+}
+
+static int sculpt_get_brush_geometry(bContext* C, ViewContext *vc,
+									 int x, int y, int* pixel_radius,
+									 float location[3])
+{
+	Scene *scene = CTX_data_scene(C);
+	Paint *paint = paint_get_active(scene);
+	Brush *brush = paint_brush(paint);
+	float window[2];
+	int hit;
+
+	window[0] = x + vc->ar->winrct.xmin;
+	window[1] = y + vc->ar->winrct.ymin;
+
+	if(vc->obact->sculpt && vc->obact->sculpt->pbvh &&
+	   sculpt_stroke_get_location(C, NULL, location, window)) {
+		*pixel_radius =
+			project_brush_radius(vc,
+								 brush_unprojected_radius(scene, brush),
+								 location);
+
+		if (*pixel_radius == 0)
+			*pixel_radius = brush_size(scene, brush);
+
+		mul_m4_v3(vc->obact->obmat, location);
+
+		hit = 1;
+	}
+	else {
+		Sculpt* sd    = CTX_data_tool_settings(C)->sculpt;
+		Brush*  brush = paint_brush(&sd->paint);
+
+		*pixel_radius = brush_size(scene, brush);
+		hit = 0;
+	}
+
+	return hit;
+}
+
+/* Draw an overlay that shows what effect the brush's texture will
+   have on brush strength */
+/* TODO: sculpt only for now */
+static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush,
+				     ViewContext *vc, int x, int y)
+{
+	rctf quad;
+
+	/* check for overlay mode */
+	if(!(brush->flag & BRUSH_TEXTURE_OVERLAY) ||

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-blender-cvs mailing list