[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