Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2014-08-28 18:40:38 +0400
committerAntony Riakiotakis <kalast@gmail.com>2014-08-28 22:41:05 +0400
commitcf3ce7322a9b6c1453869a369eba02f4fd077234 (patch)
tree94f11f57da8c00ce780e878767517cf4e428c907 /source
parent512b7383525d7b9ccdca93816a08a579db148f23 (diff)
Texture painting:
Include explicit control for texturing: This commit introduces a painting mode option, available in the slots panel. The default value "Material" will create slots from the blender material, same as just merged from the paint branch. The new option "Image", will use an explicit image field that artists can use to select the image to paint on. This will should allow painting regardless of the renderer used or for use in modifiers.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/material.c18
-rw-r--r--source/blender/blenloader/intern/readfile.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c134
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c71
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c91
-rw-r--r--source/blender/editors/space_image/image_ops.c9
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c13
-rw-r--r--source/blender/makesdna/DNA_scene_types.h15
-rw-r--r--source/blender/makesrna/intern/rna_material.c1
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c72
10 files changed, 308 insertions, 124 deletions
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 50147149b0c..e7500392c81 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -274,8 +274,7 @@ Material *localize_material(Material *ma)
if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col);
if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec);
- if (ma->texpaintslot) man->texpaintslot = MEM_dupallocN(man->texpaintslot);
-
+ ma->texpaintslot = NULL;
man->preview = NULL;
if (ma->nodetree)
@@ -1328,9 +1327,16 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
if (ma->texpaintslot) {
MEM_freeN(ma->texpaintslot);
+ ma->tot_slots = 0;
ma->texpaintslot = NULL;
}
+ if (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_IMAGE) {
+ ma->paint_active_slot = 0;
+ ma->paint_clone_slot = 0;
+ return;
+ }
+
if (use_nodes || ma->use_nodes) {
bNode *node, *active_node;
@@ -1342,10 +1348,9 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
count++;
}
- ma->tot_slots = count;
-
if (count == 0) {
ma->paint_active_slot = 0;
+ ma->paint_clone_slot = 0;
return;
}
ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
@@ -1367,10 +1372,9 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
}
}
- ma->tot_slots = count;
-
if (count == 0) {
ma->paint_active_slot = 0;
+ ma->paint_clone_slot = 0;
return;
}
@@ -1387,6 +1391,8 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
}
}
+ ma->tot_slots = count;
+
if (ma->paint_active_slot >= count) {
ma->paint_active_slot = count - 1;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 8ada7b77bab..b2e49be1a5e 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5152,6 +5152,14 @@ static void lib_link_scene(FileData *fd, Main *main)
sce->toolsettings->imapaint.stencil =
newlibadr_us(fd, sce->id.lib, sce->toolsettings->imapaint.stencil);
+ if (sce->toolsettings->imapaint.clone)
+ sce->toolsettings->imapaint.clone =
+ newlibadr_us(fd, sce->id.lib, sce->toolsettings->imapaint.clone);
+
+ if (sce->toolsettings->imapaint.canvas)
+ sce->toolsettings->imapaint.canvas =
+ newlibadr_us(fd, sce->id.lib, sce->toolsettings->imapaint.canvas);
+
sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template);
for (base = sce->base.first; base; base = next) {
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index ea6d56155cc..f596f330534 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -1363,41 +1363,87 @@ void paint_proj_mesh_data_ensure(bContext *C, Object *ob, wmOperator *op)
Mesh *me;
int layernum;
ImagePaintSettings *imapaint = &(CTX_data_tool_settings(C)->imapaint);
+ bScreen *sc;
Scene *scene = CTX_data_scene(C);
+ Main *bmain = CTX_data_main(C);
Brush *br = BKE_paint_brush(&imapaint->paint);
- /* no material, add one */
- if (ob->totcol == 0) {
- Material *ma = BKE_material_add(CTX_data_main(C), "Material");
- /* no material found, just assign to first slot */
- assign_material(ob, ma, 1, BKE_MAT_ASSIGN_USERPREF);
- proj_paint_add_slot(C, ma, NULL);
- }
- else {
- /* there may be material slots but they may be empty, check */
- int i;
-
- for (i = 1; i < ob->totcol + 1; i++) {
- Material *ma = give_current_material(ob, i);
- if (ma) {
- if (!ma->texpaintslot) {
- /* refresh here just in case */
- BKE_texpaint_slot_refresh_cache(scene, ma);
-
- /* if still no slots, we have to add */
- if (!ma->texpaintslot)
- proj_paint_add_slot(C, ma, NULL);
+ if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) {
+ /* no material, add one */
+ if (ob->totcol == 0) {
+ Material *ma = BKE_material_add(CTX_data_main(C), "Material");
+ /* no material found, just assign to first slot */
+ assign_material(ob, ma, 1, BKE_MAT_ASSIGN_USERPREF);
+ proj_paint_add_slot(C, ma, NULL);
+ }
+ else {
+ /* there may be material slots but they may be empty, check */
+ int i;
+
+ for (i = 1; i < ob->totcol + 1; i++) {
+ Material *ma = give_current_material(ob, i);
+ if (ma) {
+ if (!ma->texpaintslot) {
+ /* refresh here just in case */
+ BKE_texpaint_slot_refresh_cache(scene, ma);
+
+ /* if still no slots, we have to add */
+ if (!ma->texpaintslot) {
+ proj_paint_add_slot(C, ma, NULL);
+
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
+ ScrArea *sa;
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl;
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ ED_space_image_set(sima, scene, scene->obedit, ma->texpaintslot[0].ima);
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+ else {
+ Material *ma = BKE_material_add(CTX_data_main(C), "Material");
+ /* no material found, just assign to first slot */
+ assign_material(ob, ma, i, BKE_MAT_ASSIGN_USERPREF);
+ proj_paint_add_slot(C, ma, NULL);
}
- }
- else {
- Material *ma = BKE_material_add(CTX_data_main(C), "Material");
- /* no material found, just assign to first slot */
- assign_material(ob, ma, i, BKE_MAT_ASSIGN_USERPREF);
- proj_paint_add_slot(C, ma, NULL);
}
}
}
+ else if (imapaint->mode == IMAGEPAINT_MODE_IMAGE){
+ if (imapaint->canvas == NULL) {
+ int width;
+ int height;
+ Main *bmain = CTX_data_main(C);
+ float color[4] = {0.0, 0.0, 0.0, 1.0};
+ width = 1024;
+ height = 1024;
+ imapaint->canvas = BKE_image_add_generated(bmain, width, height, "Canvas", 32, false, IMA_GENTYPE_BLANK, color);
+
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
+ ScrArea *sa;
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl;
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ ED_space_image_set(sima, scene, scene->obedit, imapaint->canvas);
+ }
+ }
+ }
+ }
+ }
+ }
+
me = BKE_mesh_from_object(ob);
layernum = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
@@ -1449,7 +1495,8 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
else {
bScreen *sc;
Main *bmain = CTX_data_main(C);
- Material *ma;
+ Image *ima = NULL;
+ ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
/* This has to stay here to regenerate the texture paint
* cache in case we are loading a file */
@@ -1457,19 +1504,26 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
paint_proj_mesh_data_ensure(C, ob, op);
- /* set the current material active paint slot on image editor */
- ma = give_current_material(ob, ob->actcol);
+ /* entering paint mode also sets image to editors */
+ if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) {
+ Material *ma = give_current_material(ob, ob->actcol); /* set the current material active paint slot on image editor */
- if (ma->tot_slots > 0) {
- for (sc = bmain->screen.first; sc; sc = sc->id.next) {
- ScrArea *sa;
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl;
- for (sl = sa->spacedata.first; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)sl;
- ED_space_image_set(sima, scene, scene->obedit, ma->texpaintslot[ma->paint_active_slot].ima);
- }
+ if (ma->texpaintslot)
+ ima = ma->texpaintslot[ma->paint_active_slot].ima;
+ }
+ else if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) {
+ ima = imapaint->canvas;
+ }
+
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
+ ScrArea *sa;
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl;
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ ED_space_image_set(sima, scene, scene->obedit, ima);
}
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 9362510a84d..3c6fb5dfe20 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -220,6 +220,8 @@ typedef struct ProjPaintState {
MTFace *dm_mtface_stencil;
Image *stencil_ima;
+ Image *canvas_ima;
+ Image *clone_ima;
float stencil_value;
/* projection painting only */
@@ -256,6 +258,7 @@ typedef struct ProjPaintState {
bool do_layer_stencil;
bool do_layer_stencil_inv;
bool do_stencil_brush;
+ bool do_material_slots;
bool do_occlude; /* Use raytraced occlusion? - ortherwise will paint right through to the back*/
bool do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
@@ -368,16 +371,23 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int face_
MFace *mf = ps->dm_mface + face_index;
Material *ma = ps->dm->mat[mf->mat_nr];
TexPaintSlot *slot = ma->texpaintslot + ma->paint_active_slot;
- return slot ? slot->ima : NULL;
+ return slot ? slot->ima : ps->canvas_ima;
}
}
-
static TexPaintSlot *project_paint_face_clone_slot(const ProjPaintState *ps, int face_index)
{
MFace *mf = ps->dm_mface + face_index;
Material *ma = ps->dm->mat[mf->mat_nr];
- return &ma->texpaintslot[ma->paint_clone_slot];
+ return ma->texpaintslot + ma->paint_clone_slot;
+}
+
+static Image *project_paint_face_clone_image(const ProjPaintState *ps, int face_index)
+{
+ MFace *mf = ps->dm_mface + face_index;
+ Material *ma = ps->dm->mat[mf->mat_nr];
+ TexPaintSlot *slot = ma->texpaintslot + ma->paint_clone_slot;
+ return slot ? slot->ima : ps->clone_ima;
}
/* fast projection bucket array lookup, use the safe version for bound checking */
@@ -1466,7 +1476,7 @@ static ProjPixel *project_paint_uvpixel_init(
if (ps->tool == PAINT_TOOL_CLONE) {
if (ps->dm_mtface_clone) {
ImBuf *ibuf_other;
- Image *other_tpage = project_paint_face_clone_slot(ps, face_index)->ima;
+ Image *other_tpage = project_paint_face_clone_image(ps, face_index);
const MTFace *tf_other = ps->dm_mtface_clone[face_index];
if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
@@ -3005,6 +3015,19 @@ static void project_paint_begin(ProjPaintState *ps)
if (ps->do_stencil_brush)
tf_base = ps->dm_mtface_stencil;
}
+
+ if (ps->do_layer_clone) {
+ int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY);
+
+ if (layer_num != -1)
+ tf_clone_base = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
+
+ if (tf_clone_base == NULL) {
+ /* get active instead */
+ tf_clone_base = CustomData_get_layer(&ps->dm->faceData, CD_MTFACE);
+ }
+
+ }
/* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */
if (ps->dm->type != DM_TYPE_CDDM) {
@@ -3291,6 +3314,7 @@ static void project_paint_begin(ProjPaintState *ps)
/* all faces should have a valid slot, reassert here */
if (slot == NULL) {
tf_base = CustomData_get_layer(&ps->dm->faceData, CD_MTFACE);
+ tpage = ps->canvas_ima;
}
else {
if (slot != slot_last) {
@@ -3302,32 +3326,43 @@ static void project_paint_begin(ProjPaintState *ps)
/* don't allow using the same inage for painting and stencilling */
if (slot->ima == ps->stencil_ima)
continue;
+
+ tpage = slot->ima;
}
}
+ else {
+ tpage = ps->stencil_ima;
+ }
*tf = tf_base + face_index;
if (ps->do_layer_clone) {
- slot_clone = project_paint_face_clone_slot(ps, face_index);
- /* all faces should have a valid slot, reassert here */
- if (ELEM(slot_clone, NULL, slot))
+ if (ps->do_material_slots) {
+ slot_clone = project_paint_face_clone_slot(ps, face_index);
+ /* all faces should have a valid slot, reassert here */
+ if (ELEM(slot_clone, NULL, slot))
+ continue;
+ }
+ else if (ps->clone_ima == ps->canvas_ima)
continue;
-
+
tf_clone = ps->dm_mtface_clone + face_index;
-
- if (slot_clone != slot_last_clone) {
- if (!slot->uvname || !(tf_clone_base = CustomData_get_layer_named(&ps->dm->faceData, CD_MTFACE, slot_clone->uvname)))
- tf_clone_base = CustomData_get_layer(&ps->dm->faceData, CD_MTFACE);
- slot_last_clone = slot_clone;
+
+ if (ps->do_material_slots) {
+ if (slot_clone != slot_last_clone) {
+ if (!slot->uvname || !(tf_clone_base = CustomData_get_layer_named(&ps->dm->faceData, CD_MTFACE, slot_clone->uvname)))
+ tf_clone_base = CustomData_get_layer(&ps->dm->faceData, CD_MTFACE);
+ slot_last_clone = slot_clone;
+ }
}
-
+
*tf_clone = tf_clone_base + face_index;
}
/* tfbase here should be non-null! */
BLI_assert (tf_base != NULL);
- if (is_face_sel && ((slot && (tpage = slot->ima)) || (tpage = project_paint_face_paint_image(ps, face_index)))) {
+ if (is_face_sel && tpage) {
const float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
v1coSS = ps->screenCoords[mf->v1];
@@ -4480,7 +4515,13 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int
ps->scene = scene;
ps->ob = ob; /* allow override of active object */
+ ps->do_material_slots = (settings->imapaint.mode == IMAGEPAINT_MODE_MATERIAL);
ps->stencil_ima = settings->imapaint.stencil;
+ ps->canvas_ima = (!ps->do_material_slots) ?
+ settings->imapaint.canvas : NULL;
+ ps->clone_ima = (!ps->do_material_slots) ?
+ settings->imapaint.clone : NULL;
+
/* setup projection painting data */
ps->do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? 0 : 1;
ps->do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? 0 : 1;
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 0d463172f99..486bf2a5d66 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -312,7 +312,7 @@ static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, c
if (mf.v4)
dm->getVert(dm, mf.v4, &mv[3]);
- if (!slot->uvname || !(tf_base = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, slot->uvname)))
+ if (!(slot && slot->uvname && (tf_base = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, slot->uvname))))
tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE);
tf = &tf_base[a];
@@ -428,6 +428,8 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
/* first try getting a colour directly from the mesh faces if possible */
Object *ob = OBACT;
bool sample_success = false;
+ ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
+ bool use_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
if (ob) {
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
@@ -446,51 +448,58 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
view3d_operator_needs_opengl(C);
if (imapaint_pick_face(&vc, mval, &faceindex, totface)) {
- Image *image = imapaint_face_image(dm, faceindex);
-
- ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
- if (ibuf && ibuf->rect) {
- float uv[2];
- float u, v;
- imapaint_pick_uv(scene, ob, faceindex, mval, uv);
- sample_success = true;
-
- u = fmodf(uv[0], 1.0f);
- v = fmodf(uv[1], 1.0f);
-
- if (u < 0.0f) u += 1.0f;
- if (v < 0.0f) v += 1.0f;
-
- u = u * ibuf->x - 0.5f;
- v = v * ibuf->y - 0.5f;
-
- if (ibuf->rect_float) {
- float rgba_f[4];
- bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v);
- straight_to_premul_v4(rgba_f);
- if (use_palette) {
- linearrgb_to_srgb_v3_v3(color->rgb, rgba_f);
+ Image *image;
+
+ if (use_material)
+ image = imapaint_face_image(dm, faceindex);
+ else
+ image = imapaint->canvas;
+
+ if (image) {
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
+ if (ibuf && ibuf->rect) {
+ float uv[2];
+ float u, v;
+ imapaint_pick_uv(scene, ob, faceindex, mval, uv);
+ sample_success = true;
+
+ u = fmodf(uv[0], 1.0f);
+ v = fmodf(uv[1], 1.0f);
+
+ if (u < 0.0f) u += 1.0f;
+ if (v < 0.0f) v += 1.0f;
+
+ u = u * ibuf->x - 0.5f;
+ v = v * ibuf->y - 0.5f;
+
+ if (ibuf->rect_float) {
+ float rgba_f[4];
+ bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v);
+ straight_to_premul_v4(rgba_f);
+ if (use_palette) {
+ linearrgb_to_srgb_v3_v3(color->rgb, rgba_f);
+ }
+ else {
+ linearrgb_to_srgb_v3_v3(rgba_f, rgba_f);
+ BKE_brush_color_set(scene, br, rgba_f);
+ }
}
else {
- linearrgb_to_srgb_v3_v3(rgba_f, rgba_f);
- BKE_brush_color_set(scene, br, rgba_f);
- }
- }
- else {
- unsigned char rgba[4];
- bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v);
- if (use_palette) {
- rgb_uchar_to_float(color->rgb, rgba);
- }
- else {
- float rgba_f[3];
- rgb_uchar_to_float(rgba_f, rgba);
- BKE_brush_color_set(scene, br, rgba_f);
+ unsigned char rgba[4];
+ bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v);
+ if (use_palette) {
+ rgb_uchar_to_float(color->rgb, rgba);
+ }
+ else {
+ float rgba_f[3];
+ rgb_uchar_to_float(rgba_f, rgba);
+ BKE_brush_color_set(scene, br, rgba_f);
+ }
}
}
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
}
-
- BKE_image_release_ibuf(image, ibuf, NULL);
}
}
dm->release(dm);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index f402f1cb4c8..0a3713a41e4 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1907,7 +1907,6 @@ static int image_new_exec(bContext *C, wmOperator *op)
char *name = _name;
float color[4];
int width, height, floatbuf, gen_type, alpha;
- bool stencil;
/* retrieve state */
sima = CTX_wm_space_image(C);
@@ -1927,7 +1926,6 @@ static int image_new_exec(bContext *C, wmOperator *op)
gen_type = RNA_enum_get(op->ptr, "generated_type");
RNA_float_get_array(op->ptr, "color", color);
alpha = RNA_boolean_get(op->ptr, "alpha");
- stencil = RNA_boolean_get(op->ptr, "texstencil");
if (!alpha)
color[3] = 1.0f;
@@ -1960,13 +1958,6 @@ static int image_new_exec(bContext *C, wmOperator *op)
tex->ima = ima;
ED_area_tag_redraw(CTX_wm_area(C));
}
- else if (stencil) {
- ImagePaintSettings *imapaint = &(CTX_data_tool_settings(C)->imapaint);
-
- if (imapaint->stencil)
- id_us_min(&imapaint->stencil->id);
- imapaint->stencil = ima;
- }
}
BKE_image_signal(ima, (sima) ? &sima->iuser : NULL, IMA_SIGNAL_USER_NEW_IMAGE);
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index e571584a10f..dd9b9dea02a 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -212,7 +212,8 @@ static Material *give_current_material_or_def(Object *ob, int matnr)
static struct TextureDrawState {
Object *ob;
- Image *stencil;
+ Image *stencil; /* texture painting stencil */
+ Image *canvas; /* texture painting canvas, for image mode */
bool stencil_invert;
bool use_game_mat;
int is_lit, is_tex;
@@ -221,7 +222,8 @@ static struct TextureDrawState {
unsigned char obcol[4];
float stencil_col[4];
bool is_texpaint;
-} Gtexdraw = {NULL, NULL, false, false, 0, 0, 0, false, {0, 0, 0, 0}, {0.0f, 0.0f, 0.0f, 1.0f}, false};
+ bool texpaint_material; /* use material slots for texture painting */
+} Gtexdraw = {NULL, NULL, NULL, false, false, 0, 0, 0, false, {0, 0, 0, 0}, {0.0f, 0.0f, 0.0f, 1.0f}, false, false};
static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
{
@@ -280,7 +282,10 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
alphablend = GPU_BLEND_ALPHA;
}
else if (texpaint && ma) {
- ima = ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
+ if (gtexdraw.texpaint_material)
+ ima = ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
+ else
+ ima = gtexdraw.canvas;
}
else
textured = 0;
@@ -394,6 +399,8 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
Gtexdraw.stencil_invert = ((imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0);
Gtexdraw.is_texpaint = (ob->mode == OB_MODE_TEXTURE_PAINT);
copy_v3_v3(Gtexdraw.stencil_col, imapaint->stencil_col);
+ Gtexdraw.texpaint_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
+ Gtexdraw.canvas = (Gtexdraw.texpaint_material) ? NULL : imapaint->canvas;
Gtexdraw.is_tex = is_tex;
/* load the stencil texture here */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index d7bc8e56e38..c8b8e4d52a4 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -841,12 +841,14 @@ typedef struct ImagePaintSettings {
short seam_bleed, normal_angle;
short screen_grab_size[2]; /* capture size for re-projection */
- int pad1;
+ int mode; /* mode used for texture painting */
- void *paintcursor; /* wm handle */
- struct Image *stencil; /* workaround until we support true layer masks */
+ void *paintcursor; /* wm handle */
+ struct Image *stencil; /* workaround until we support true layer masks */
+ struct Image *clone; /* clone layer for image mode for projective texture painting */
+ struct Image *canvas; /* canvas when the explicit system is used for painting */
float stencil_col[3];
- float pad2;
+ float pad1;
} ImagePaintSettings;
/* ------------------------------------------- */
@@ -1708,6 +1710,11 @@ typedef enum SculptFlags {
SCULPT_DYNTOPO_DETAIL_CONSTANT = (1 << 13)
} SculptFlags;
+typedef enum ImagePaintMode {
+ IMAGEPAINT_MODE_MATERIAL, /* detect texture paint slots from the material */
+ IMAGEPAINT_MODE_IMAGE, /* select texture paint image directly */
+} ImagePaintMode;
+
#if (DNA_DEPRECATED_GCC_POISON == 1)
#pragma GCC poison SCULPT_SYMM_X SCULPT_SYMM_Y SCULPT_SYMM_Z SCULPT_SYMMETRY_FEATHER
#endif
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index c395b963d48..37b6947cfac 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -181,7 +181,6 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *s
bScreen *sc;
Material *ma = ptr->id.data;
-
if (ma->use_nodes && ma->nodetree && BKE_scene_use_new_shading_nodes(scene)) {
struct bNode *node;
int index = 0;
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index af6cf493f1e..c4b5461dece 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -34,8 +34,13 @@
#include "DNA_ID.h"
#include "DNA_scene_types.h"
#include "DNA_brush_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
#include "BKE_paint.h"
+#include "BKE_material.h"
+
+#include "ED_image.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -286,11 +291,44 @@ static void rna_Paint_brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Po
WM_main_add_notifier(NC_BRUSH | NA_EDITED, br);
}
-static void rna_ImaPaint_stencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
+static void rna_ImaPaint_viewport_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
/* not the best solution maybe, but will refresh the 3D viewport */
WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
}
+
+static void rna_ImaPaint_mode_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+{
+ Object *ob = OBACT;
+
+ /* of course we need to invalidate here */
+ BKE_texpaint_slots_refresh_object(scene, ob);
+
+ /* we assume that changing the current mode will invalidate the uv layers so we need to tag an update */
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_main_add_notifier(NC_GEOM | ND_DATA, &ob->id);
+}
+
+static void rna_ImaPaint_canvas_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
+{
+ bScreen *sc;
+ Image *ima = scene->toolsettings->imapaint.canvas;
+
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
+ ScrArea *sa;
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl;
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)sl;
+ ED_space_image_set(sima, scene, scene->obedit, ima);
+ }
+ }
+ }
+ }
+
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
+}
#else
static void rna_def_palettecolor(BlenderRNA *brna)
@@ -571,6 +609,14 @@ static void rna_def_image_paint(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+
+ static EnumPropertyItem paint_type_items[] = {
+ {IMAGEPAINT_MODE_MATERIAL, "MATERIAL", 0,
+ "Material", "Detect image slots from the material"},
+ {IMAGEPAINT_MODE_IMAGE, "IMAGE", 0,
+ "Image", "Set image for texture painting directly"},
+ {0, NULL, 0, NULL, NULL}
+ };
srna = RNA_def_struct(brna, "ImagePaint", "Paint");
RNA_def_struct_sdna(srna, "ImagePaintSettings");
@@ -596,24 +642,35 @@ static void rna_def_image_paint(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_stencil_layer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_STENCIL);
RNA_def_property_ui_text(prop, "Stencil Layer", "Set the mask layer from the UV map buttons");
- RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_stencil_update");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_viewport_update");
prop = RNA_def_property(srna, "invert_stencil", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_STENCIL_INV);
RNA_def_property_ui_text(prop, "Invert", "Invert the stencil layer");
- RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_stencil_update");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_viewport_update");
prop = RNA_def_property(srna, "stencil_image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "stencil");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Stencil Image", "Image used as stencil");
- RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_stencil_update");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_viewport_update");
+ prop = RNA_def_property(srna, "canvas", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Canvas", "Image used as canvas");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_canvas_update");
+
+ prop = RNA_def_property(srna, "clone_image", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "clone");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Clone Image", "Image used as clone source");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
prop = RNA_def_property(srna, "stencil_color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_float_sdna(prop, NULL, "stencil_col");
RNA_def_property_ui_text(prop, "Stencil Color", "Stencil color in the viewport");
- RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_stencil_update");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_viewport_update");
prop = RNA_def_property(srna, "use_clone_layer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_CLONE);
@@ -634,6 +691,11 @@ static void rna_def_image_paint(BlenderRNA *brna)
prop = RNA_def_int_array(srna, "screen_grab_size", 2, NULL, 0, 0, "screen_grab_size",
"Size to capture the image for re-projecting", 0, 0);
RNA_def_property_range(prop, 512, 16384);
+
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, paint_type_items);
+ RNA_def_property_ui_text(prop, "Mode", "Mode of operation for projection painting");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_mode_update");
}
static void rna_def_particle_edit(BlenderRNA *brna)