diff options
author | Nicholas Bishop <nicholasbishop@gmail.com> | 2010-07-25 09:01:55 +0400 |
---|---|---|
committer | Nicholas Bishop <nicholasbishop@gmail.com> | 2010-07-25 09:01:55 +0400 |
commit | ef74fc391d7d03061094a507939bf2e5f241c93c (patch) | |
tree | 35ebf066fe8d52f0741b7eb4bc70cb8e48ec071f | |
parent | 164e552e811c2b3115a4087fc50a025baaa4aa82 (diff) |
== VPaint ==
Enabled textures for vpaint brushes. Not all of the texture options work yet.
-rw-r--r-- | release/scripts/ui/space_view3d_toolbar.py | 3 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_intern.h | 8 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_stroke.c | 7 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_utils.c | 115 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 44 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 161 |
6 files changed, 182 insertions, 156 deletions
diff --git a/release/scripts/ui/space_view3d_toolbar.py b/release/scripts/ui/space_view3d_toolbar.py index 850d0dc8b8a..454a71adc10 100644 --- a/release/scripts/ui/space_view3d_toolbar.py +++ b/release/scripts/ui/space_view3d_toolbar.py @@ -795,6 +795,7 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel): def poll(self, context): settings = self.paint_settings(context) return (settings and settings.brush and (context.sculpt_object or + context.vertex_paint_object or context.texture_paint_object)) def draw(self, context): @@ -808,7 +809,7 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel): col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8) - if context.sculpt_object: + if context.sculpt_object or context.vertex_paint_object: #XXX duplicated from properties_texture.py wide_ui = context.region.width > narrowui diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 3d4a426995e..adfa1cddc26 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -32,6 +32,7 @@ #include "BLI_pbvh.h" struct bContext; +struct Brush; struct Scene; struct Object; struct Mesh; @@ -61,6 +62,7 @@ void paint_stroke_free(struct PaintStroke *stroke); int paint_stroke_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int paint_stroke_exec(struct bContext *C, struct wmOperator *op); struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke); +void paint_stroke_projection_mat(struct PaintStroke *stroke, float (**pmat)[4]); void *paint_stroke_mode_data(struct PaintStroke *stroke); void paint_stroke_set_mode_data(struct PaintStroke *stroke, void *mode_data); @@ -136,6 +138,12 @@ void paint_tag_partial_redraw(struct bContext *C, struct Object *ob); struct MultiresModifierData *paint_multires_active(struct Scene *scene, struct Object *ob); +float brush_tex_strength(struct ViewContext *vc, + float pmat[4][4], struct Brush *br, + float co[3], float mask, const float len, + float pixel_radius, float radius3d, + float special_rotation, float tex_mouse[2]); + /* stroke operator */ typedef enum wmBrushStrokeMode { WM_BRUSHSTROKE_NORMAL, diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index de13713def7..c0d7409754d 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -64,6 +64,7 @@ struct PaintStroke { /* Cached values */ ViewContext vc; + float project_mat[4][4]; bglMats mats; Brush *brush; @@ -805,6 +806,7 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev PaintStroke *stroke = op->customdata; view3d_set_viewcontext(C, &vc); // XXX + view3d_get_object_project_mat(vc.rv3d, vc.obact, stroke->project_mat); /* Tablet */ if(event->custom == EVT_DATA_TABLET) { @@ -1045,6 +1047,11 @@ ViewContext *paint_stroke_view_context(PaintStroke *stroke) return &stroke->vc; } +void paint_stroke_projection_mat(PaintStroke *stroke, float (**pmat)[4]) +{ + *pmat = &stroke->project_mat; +} + void *paint_stroke_mode_data(struct PaintStroke *stroke) { return stroke->mode_data; diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index cef40d7c19b..0c03c7e3e1b 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -36,6 +36,9 @@ #include "WM_api.h" #include "WM_types.h" +#include "RE_render_ext.h" +#include "RE_shader_ext.h" + #include "paint_intern.h" /* 3D Paint */ @@ -453,3 +456,115 @@ void paint_get_redraw_planes(float planes[4][4], ARegion *ar, if(pbvh) BLI_pbvh_update(pbvh, PBVH_UpdateRedraw, NULL); } + +float get_tex_pixel(Brush* br, float u, float v) +{ + TexResult texres; + float co[3]; + int hasrgb; + + co[0] = u; + co[1] = v; + co[2] = 0; + + memset(&texres, 0, sizeof(TexResult)); + hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 1, &texres); + + if (hasrgb & TEX_RGB) + texres.tin = (0.35*texres.tr + 0.45*texres.tg + 0.2*texres.tb)*texres.ta; + + return texres.tin; +} + +/* return a multiplier for brush strength at a coordinate, + incorporating texture, curve control, and masking + + TODO: pulled almost directly from sculpt, still needs + to be prettied up +*/ +float brush_tex_strength(ViewContext *vc, + float pmat[4][4], Brush *br, + float co[3], float mask, const float len, + float pixel_radius, float radius3d, + float special_rotation, float tex_mouse[2]) +{ + MTex *mtex = &br->mtex; + float avg= 1; + + if(!mtex->tex) { + avg= 1; + } + else if(mtex->brush_map_mode == MTEX_MAP_MODE_3D) { + float jnk; + + /* Get strength by feeding the vertex + location directly into a texture */ + externtex(mtex, co, &avg, + &jnk, &jnk, &jnk, &jnk); + } + else { + float rotation = -mtex->rot; + float x, y, point_2d[3]; + float radius; + + view3d_project_float(vc->ar, co, point_2d, pmat); + + /* if fixed mode, keep coordinates relative to mouse */ + if(mtex->brush_map_mode == MTEX_MAP_MODE_FIXED) { + rotation += special_rotation; + + point_2d[0] -= tex_mouse[0]; + point_2d[1] -= tex_mouse[1]; + + radius = pixel_radius; // use pressure adjusted size for fixed mode + + x = point_2d[0]; + y = point_2d[1]; + } + else /* else (mtex->brush_map_mode == MTEX_MAP_MODE_TILED), + leave the coordinates relative to the screen */ + { + radius = brush_size(br); // use unadjusted size for tiled mode + + x = point_2d[0] - vc->ar->winrct.xmin; + y = point_2d[1] - vc->ar->winrct.ymin; + } + + x /= vc->ar->winx; + y /= vc->ar->winy; + + if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) { + x -= 0.5f; + y -= 0.5f; + } + + x *= vc->ar->winx / radius; + y *= vc->ar->winy / radius; + + /* 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 (rotation > 0.001 || rotation < -0.001) { + const float angle = atan2(y, x) + rotation; + const float flen = sqrtf(x*x + y*y); + + x = flen * cos(angle); + y = flen * sin(angle); + } + + x *= br->mtex.size[0]; + y *= br->mtex.size[1]; + + x += br->mtex.ofs[0]; + y += br->mtex.ofs[1]; + + avg = get_tex_pixel(br, x, y); + } + + avg += br->texture_sample_bias; + + avg *= brush_curve_strength(br, len, radius3d); /* Falloff curve */ + avg*= 1 - mask; + + return avg; +} diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 45c790723b1..5890938a01d 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1688,10 +1688,25 @@ static void vpaint_blend(Brush *brush, float col[4], float alpha) } } +static float tex_strength(Brush *brush, PaintStroke *stroke, + float co[3], float mask, float len, + float radius3d) +{ + ViewContext *vc = paint_stroke_view_context(stroke); + float (*pmat)[4]; + float tex_mouse[2] = {0,0}; /* TODO */ + + paint_stroke_projection_mat(stroke, &pmat); + + return brush_tex_strength(vc, pmat, brush, co, 0, len, + brush->size, radius3d, 0, + tex_mouse); +} + /* apply paint at specified coordinate returns 1 if paint was applied, 0 otherwise */ -static int vpaint_paint_coord(VPaint *vp, VPaintData *vpd, float co[3], - float col[4], float orig_col[4], +static int vpaint_paint_coord(VPaint *vp, PaintStroke *stroke, + float co[3], float col[4], float center[3], float radius, float radius_squared) { @@ -1704,8 +1719,7 @@ static int vpaint_paint_coord(VPaint *vp, VPaintData *vpd, float co[3], dist = sqrtf(dist_squared); strength = brush->alpha * - brush_curve_strength(brush, dist, - radius); + tex_strength(brush, stroke, co, 0, dist, radius); vpaint_blend(brush, col, strength); @@ -1715,8 +1729,9 @@ static int vpaint_paint_coord(VPaint *vp, VPaintData *vpd, float co[3], return 0; } -static void vpaint_nodes_grids(VPaint *vp, VPaintData *vpd, DMGridData **grids, - GridKey *gridkey, int *grid_indices, int totgrid, +static void vpaint_nodes_grids(VPaint *vp, PaintStroke *stroke, + DMGridData **grids, GridKey *gridkey, + int *grid_indices, int totgrid, int gridsize, int active, float center[3], float radius) { @@ -1734,9 +1749,8 @@ static void vpaint_nodes_grids(VPaint *vp, VPaintData *vpd, DMGridData **grids, float *co = GRIDELEM_CO(elem, gridkey); float *gridcol = GRIDELEM_COLOR(elem, gridkey)[active]; - vpaint_paint_coord(vp, vpd, co, + vpaint_paint_coord(vp, stroke, co, gridcol, - NULL, /* TODO */ center, radius, radius_squared); } @@ -1744,7 +1758,7 @@ static void vpaint_nodes_grids(VPaint *vp, VPaintData *vpd, DMGridData **grids, } } -static void vpaint_nodes_faces(VPaint *vp, VPaintData *vpd, MFace *mface, +static void vpaint_nodes_faces(VPaint *vp, PaintStroke *stroke, MFace *mface, MVert *mvert, CustomData *fdata, int *face_indices, int totface, float center[3], float radius) @@ -1775,7 +1789,7 @@ static void vpaint_nodes_faces(VPaint *vp, VPaintData *vpd, MFace *mface, fcol[2] = mcol[cndx].r / 255.0f; fcol[3] = mcol[cndx].a / 255.0f; - vpaint_paint_coord(vp, vpd, co, fcol, NULL /* TODO */, center, + vpaint_paint_coord(vp, stroke, co, fcol, center, radius, radius_squared); mcol[cndx].b = fcol[0] * 255.0f; @@ -1804,7 +1818,8 @@ static int vpaint_find_gridkey_active_layer(CustomData *fdata, GridKey *gridkey) return -1; } -static void vpaint_nodes(VPaint *vp, VPaintData *vpd, PBVH *pbvh, +static void vpaint_nodes(VPaint *vp, PaintStroke *stroke, + PBVH *pbvh, PBVHNode **nodes, int totnode, float center[3], float radius) { @@ -1834,14 +1849,14 @@ static void vpaint_nodes(VPaint *vp, VPaintData *vpd, PBVH *pbvh, gridkey); if(active != -1) { - vpaint_nodes_grids(vp, vpd, grids, gridkey, + vpaint_nodes_grids(vp, stroke, grids, gridkey, grid_indices, totgrid, gridsize, active, center, radius); } } else { - vpaint_nodes_faces(vp, vpd, mface, mvert, fdata, + vpaint_nodes_faces(vp, stroke, mface, mvert, fdata, face_indices, totface, center, radius); } @@ -1977,7 +1992,6 @@ static void vpaint_stroke_update_step(bContext *C, PaintStroke *stroke, PointerRNA *itemptr) { VPaint *vp= CTX_data_tool_settings(C)->vpaint; - VPaintData *vpd = paint_stroke_mode_data(stroke); ViewContext *vc = paint_stroke_view_context(stroke); Brush *brush = paint_brush(&vp->paint); Object *ob = vc->obact; @@ -1997,7 +2011,7 @@ static void vpaint_stroke_update_step(bContext *C, PaintStroke *stroke, BLI_pbvh_search_gather(ob->paint->pbvh, BLI_pbvh_search_sphere_cb, &search_data, &nodes, &totnode); - vpaint_nodes(vp, vpd, ob->paint->pbvh, nodes, totnode, + vpaint_nodes(vp, stroke, ob->paint->pbvh, nodes, totnode, center, radius); if(nodes) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index c63dc9e1199..214abb8cab8 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -83,10 +83,6 @@ #include "RNA_access.h" #include "RNA_define.h" - -#include "RE_render_ext.h" -#include "RE_shader_ext.h" - #include "GPU_buffers.h" #include <math.h> @@ -188,7 +184,7 @@ typedef struct StrokeCache { int first_time; /* Beginning of stroke may do some things special */ - bglMats *mats; + float project_mat[4][4]; /* Clean this up! */ ViewContext *vc; @@ -221,32 +217,6 @@ typedef struct StrokeCache { float plane_trim_squared; } StrokeCache; -/* ===== OPENGL ===== - * - * Simple functions to get data from the GL - */ - -/* Convert a point in model coordinates to 2D screen coordinates. */ -static void projectf(bglMats *mats, const float v[3], float p[2]) -{ - double ux, uy, uz; - - gluProject(v[0],v[1],v[2], mats->modelview, mats->projection, - (GLint *)mats->viewport, &ux, &uy, &uz); - p[0]= ux; - p[1]= uy; -} - -/*XXX: static void project(bglMats *mats, const float v[3], short p[2]) -{ - float f[2]; - projectf(mats, v, f); - - p[0]= f[0]; - p[1]= f[1]; -} -*/ - /************************ Brush Testing *******************/ typedef struct SculptBrushTest { @@ -567,25 +537,6 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather) } } -float get_tex_pixel(Brush* br, float u, float v) -{ - TexResult texres; - float co[3]; - int hasrgb; - - co[0] = u; - co[1] = v; - co[2] = 0; - - memset(&texres, 0, sizeof(TexResult)); - hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 1, &texres); - - if (hasrgb & TEX_RGB) - texres.tin = (0.35*texres.tr + 0.45*texres.tg + 0.2*texres.tb)*texres.ta; - - return texres.tin; -} - #if 0 /* Get a pixel from the texcache at (px, py) */ @@ -627,100 +578,32 @@ static float get_texcache_pixel_bilinear(const SculptSession *ss, float u, float #endif -/* Return a multiplier for brush strength on a particular vertex. */ -static float tex_strength(SculptSession *ss, Brush *br, float *point, float mask, const float len) +static float tex_strength(SculptSession *ss, Brush *br, float *co, float mask, const float len) { - MTex *mtex = &br->mtex; - float avg= 1; + float mco[3]; - if(!mtex->tex) { - avg= 1; - } - else if(mtex->brush_map_mode == MTEX_MAP_MODE_3D) { - float jnk; - - /* Get strength by feeding the vertex - location directly into a texture */ - externtex(mtex, point, &avg, - &jnk, &jnk, &jnk, &jnk); - } - else if(ss->texcache) { - float rotation = -mtex->rot; - float x, y, point_2d[3]; - float radius; - - /* if the active area is being applied for symmetry, flip it - across the symmetry axis and rotate it back to the orignal - position in order to project it. This insures that the - brush texture will be oriented correctly. */ - - flip_coord(point_2d, point, ss->cache->mirror_symmetry_pass); - - if (ss->cache->radial_symmetry_pass) - mul_m4_v3(ss->cache->symm_rot_mat_inv, point_2d); - - projectf(ss->cache->mats, point_2d, point_2d); - - /* if fixed mode, keep coordinates relative to mouse */ - if(mtex->brush_map_mode == MTEX_MAP_MODE_FIXED) { - rotation += ss->cache->special_rotation; - - point_2d[0] -= ss->cache->tex_mouse[0]; - point_2d[1] -= ss->cache->tex_mouse[1]; - - radius = ss->cache->pixel_radius; // use pressure adjusted size for fixed mode - - x = point_2d[0]; - y = point_2d[1]; - } - else /* else (mtex->brush_map_mode == MTEX_MAP_MODE_TILED), - leave the coordinates relative to the screen */ - { - radius = brush_size(br); // use unadjusted size for tiled mode + /* if the active area is being applied for symmetry, flip it + across the symmetry axis and rotate it back to the orignal + position in order to project it. This insures that the + brush texture will be oriented correctly. */ + if(br->mtex.tex && + br->mtex.brush_map_mode != MTEX_MAP_MODE_3D) { + flip_coord(mco, co, ss->cache->mirror_symmetry_pass); - x = point_2d[0] - ss->cache->vc->ar->winrct.xmin; - y = point_2d[1] - ss->cache->vc->ar->winrct.ymin; - } - - x /= ss->cache->vc->ar->winx; - y /= ss->cache->vc->ar->winy; + if(ss->cache->radial_symmetry_pass) + mul_m4_v3(ss->cache->symm_rot_mat_inv, mco); - if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) { - x -= 0.5f; - y -= 0.5f; - } - - x *= ss->cache->vc->ar->winx / radius; - y *= ss->cache->vc->ar->winy / radius; - - /* 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 (rotation > 0.001 || rotation < -0.001) { - const float angle = atan2(y, x) + rotation; - const float flen = sqrtf(x*x + y*y); - - x = flen * cos(angle); - y = flen * sin(angle); - } - - x *= br->mtex.size[0]; - y *= br->mtex.size[1]; - - x += br->mtex.ofs[0]; - y += br->mtex.ofs[1]; - - avg = get_tex_pixel(br, x, y); + co = mco; } - - avg += br->texture_sample_bias; - - avg *= brush_curve_strength(br, len, ss->cache->radius); /* Falloff curve */ - avg*= 1 - mask; - return avg; + return brush_tex_strength(ss->cache->vc, + ss->cache->project_mat, br, co, mask, len, + ss->cache->pixel_radius, ss->cache->radius, + ss->cache->special_rotation, + ss->cache->tex_mouse); } + /* Handles clipping against a mirror modifier and SCULPT_LOCK axis flags */ static void sculpt_clip(Sculpt *sd, SculptSession *ss, float *co, const float val[3]) { @@ -2727,8 +2610,6 @@ static void sculpt_cache_free(StrokeCache *cache) { if(cache->face_norms) MEM_freeN(cache->face_norms); - if(cache->mats) - MEM_freeN(cache->mats); MEM_freeN(cache); } @@ -2811,8 +2692,8 @@ static void sculpt_update_cache_invariants(bContext* C, Sculpt *sd, SculptSessio cache->brush = brush; - cache->mats = MEM_callocN(sizeof(bglMats), "sculpt bglMats"); - view3d_get_transformation(vc->ar, vc->rv3d, vc->obact, cache->mats); + /* TODO: use paintstroke for this */ + view3d_get_object_project_mat(cache->vc->rv3d, ob, cache->project_mat); viewvector(cache->vc->rv3d, cache->vc->rv3d->twmat[3], cache->true_view_normal); /* Initialize layer brush displacements and persistent coords */ |