forked from bartvdbraak/blender
Support for textures in vertex painting.
Developer notes: this commit does painting in sRGB space. Since colours are stored im byte per component formats, expect this to have the usual dark fringing issues. Speed wise vertex paint could use some optimization, for instance we could store the screen space vertex positions on initialization like we do for texture painting, but this is for another time. Also noticed that vertex painting suffers from the subsurf + mirror issue too :/ Apart from that it's quite exciting how easy it is to add support for texturing now that proper abstractions for texture sampling have been done :)
This commit is contained in:
parent
604c75bb80
commit
d97050a7f6
@ -751,7 +751,7 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
|
|||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
settings = cls.paint_settings(context)
|
settings = cls.paint_settings(context)
|
||||||
return (settings and settings.brush and
|
return (settings and settings.brush and
|
||||||
(context.sculpt_object or context.image_paint_object))
|
(context.sculpt_object or context.image_paint_object or context.vertex_paint_object))
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
|
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
|
#include "BLI_math_color.h"
|
||||||
#include "BLI_memarena.h"
|
#include "BLI_memarena.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
#include "BLI_ghash.h"
|
#include "BLI_ghash.h"
|
||||||
@ -854,8 +855,8 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* whats _dl mean? */
|
/* whats _dl mean? */
|
||||||
static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float co[3],
|
static float calc_vp_strength_col_dl(VPaint *vp, ViewContext *vc, const float co[3],
|
||||||
const float mval[2], const float brush_size_pressure)
|
const float mval[2], const float brush_size_pressure, float rgba[4])
|
||||||
{
|
{
|
||||||
float vertco[2];
|
float vertco[2];
|
||||||
|
|
||||||
@ -871,19 +872,26 @@ static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float co[3],
|
|||||||
if (dist_squared <= brush_size_pressure * brush_size_pressure) {
|
if (dist_squared <= brush_size_pressure * brush_size_pressure) {
|
||||||
Brush *brush = paint_brush(&vp->paint);
|
Brush *brush = paint_brush(&vp->paint);
|
||||||
const float dist = sqrtf(dist_squared);
|
const float dist = sqrtf(dist_squared);
|
||||||
|
if (brush->mtex.tex) {
|
||||||
|
if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D)
|
||||||
|
BKE_brush_sample_tex_3D(vc->scene, brush, co, rgba, 0, NULL);
|
||||||
|
else
|
||||||
|
BKE_brush_sample_tex_3D(vc->scene, brush, vertco, rgba, 0, NULL);
|
||||||
|
}
|
||||||
return BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure);
|
return BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zero_v4(rgba);
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc,
|
static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc,
|
||||||
float vpimat[3][3], const DMCoNo *v_co_no,
|
float vpimat[3][3], const DMCoNo *v_co_no,
|
||||||
const float mval[2],
|
const float mval[2],
|
||||||
const float brush_size_pressure, const float brush_alpha_pressure)
|
const float brush_size_pressure, const float brush_alpha_pressure, float rgba[4])
|
||||||
{
|
{
|
||||||
float strength = calc_vp_strength_dl(vp, vc, v_co_no->co, mval, brush_size_pressure);
|
float strength = calc_vp_strength_col_dl(vp, vc, v_co_no->co, mval, brush_size_pressure, rgba);
|
||||||
|
|
||||||
if (strength > 0.0f) {
|
if (strength > 0.0f) {
|
||||||
float alpha = brush_alpha_pressure * strength;
|
float alpha = brush_alpha_pressure * strength;
|
||||||
@ -2307,7 +2315,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
|
|||||||
#define WP_BLUR_ACCUM(v_idx_var) \
|
#define WP_BLUR_ACCUM(v_idx_var) \
|
||||||
{ \
|
{ \
|
||||||
const unsigned int vidx = v_idx_var; \
|
const unsigned int vidx = v_idx_var; \
|
||||||
const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure); \
|
const float fac = calc_vp_strength_col_dl(wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure, NULL); \
|
||||||
if (fac > 0.0f) { \
|
if (fac > 0.0f) { \
|
||||||
MDeformWeight *dw = dw_func(&me->dvert[vidx], wpi.vgroup_active); \
|
MDeformWeight *dw = dw_func(&me->dvert[vidx], wpi.vgroup_active); \
|
||||||
paintweight += dw ? (dw->weight * fac) : 0.0f; \
|
paintweight += dw ? (dw->weight * fac) : 0.0f; \
|
||||||
@ -2378,7 +2386,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
|
|||||||
unsigned int vidx = v_idx_var; \
|
unsigned int vidx = v_idx_var; \
|
||||||
if (me->dvert[vidx].flag) { \
|
if (me->dvert[vidx].flag) { \
|
||||||
alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], \
|
alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], \
|
||||||
mval, brush_size_pressure, brush_alpha_pressure); \
|
mval, brush_size_pressure, brush_alpha_pressure, NULL); \
|
||||||
if (alpha) { \
|
if (alpha) { \
|
||||||
do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); \
|
do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); \
|
||||||
} \
|
} \
|
||||||
@ -2662,6 +2670,8 @@ typedef struct VPaintData {
|
|||||||
/* mpoly -> mface mapping */
|
/* mpoly -> mface mapping */
|
||||||
MemArena *polyfacemap_arena;
|
MemArena *polyfacemap_arena;
|
||||||
ListBase *polyfacemap;
|
ListBase *polyfacemap;
|
||||||
|
|
||||||
|
bool is_texbrush;
|
||||||
} VPaintData;
|
} VPaintData;
|
||||||
|
|
||||||
static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me)
|
static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me)
|
||||||
@ -2698,6 +2708,7 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl
|
|||||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||||
struct PaintStroke *stroke = op->customdata;
|
struct PaintStroke *stroke = op->customdata;
|
||||||
VPaint *vp = ts->vpaint;
|
VPaint *vp = ts->vpaint;
|
||||||
|
Brush *brush = paint_brush(&vp->paint);
|
||||||
struct VPaintData *vpd;
|
struct VPaintData *vpd;
|
||||||
Object *ob = CTX_data_active_object(C);
|
Object *ob = CTX_data_active_object(C);
|
||||||
Mesh *me;
|
Mesh *me;
|
||||||
@ -2727,6 +2738,8 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl
|
|||||||
vpd->indexar = get_indexarray(me);
|
vpd->indexar = get_indexarray(me);
|
||||||
vpd->paintcol = vpaint_get_current_col(vp);
|
vpd->paintcol = vpaint_get_current_col(vp);
|
||||||
|
|
||||||
|
vpd->is_texbrush = !(brush->vertexpaint_tool == PAINT_BLEND_BLUR) &&
|
||||||
|
brush->mtex.tex;
|
||||||
|
|
||||||
/* are we painting onto a modified mesh?,
|
/* are we painting onto a modified mesh?,
|
||||||
* if not we can skip face map trickyness */
|
* if not we can skip face map trickyness */
|
||||||
@ -2803,12 +2816,24 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
|
|||||||
|
|
||||||
ml = me->mloop + mpoly->loopstart;
|
ml = me->mloop + mpoly->loopstart;
|
||||||
for (i = 0; i < mpoly->totloop; i++, ml++) {
|
for (i = 0; i < mpoly->totloop; i++, ml++) {
|
||||||
|
float rgba[4];
|
||||||
|
unsigned int paintcol;
|
||||||
alpha = calc_vp_alpha_dl(vp, vc, vpd->vpimat,
|
alpha = calc_vp_alpha_dl(vp, vc, vpd->vpimat,
|
||||||
&vpd->vertexcosnos[ml->v], mval,
|
&vpd->vertexcosnos[ml->v], mval,
|
||||||
brush_size_pressure, brush_alpha_pressure);
|
brush_size_pressure, brush_alpha_pressure, rgba);
|
||||||
|
|
||||||
|
if (vpd->is_texbrush) {
|
||||||
|
float rgba_br[3];
|
||||||
|
rgb_uchar_to_float(rgba_br, (const unsigned char *)&vpd->paintcol);
|
||||||
|
mul_v3_v3(rgba_br, rgba);
|
||||||
|
rgb_float_to_uchar((unsigned char *)&paintcol, rgba_br);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
paintcol = vpd->paintcol;
|
||||||
|
|
||||||
if (alpha > 0.0f) {
|
if (alpha > 0.0f) {
|
||||||
const int alpha_i = (int)(alpha * 255.0f);
|
const int alpha_i = (int)(alpha * 255.0f);
|
||||||
lcol[i] = vpaint_blend(vp, lcol[i], lcolorig[i], vpd->paintcol, alpha_i, brush_alpha_pressure_i);
|
lcol[i] = vpaint_blend(vp, lcol[i], lcolorig[i], paintcol, alpha_i, brush_alpha_pressure_i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user