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
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_customdata.h8
-rw-r--r--source/blender/blenkernel/intern/customdata.c84
-rw-r--r--source/blender/include/butspace.h2
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h9
-rw-r--r--source/blender/src/buttons_editing.c92
-rw-r--r--source/blender/src/imagepaint.c171
7 files changed, 270 insertions, 98 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index c84b690bc49..10791968f79 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -198,8 +198,12 @@ int CustomData_get_layer_index(const struct CustomData *data, int type);
int CustomData_get_named_layer_index(const struct CustomData *data, int type, char *name);
int CustomData_get_active_layer_index(const struct CustomData *data, int type);
int CustomData_get_render_layer_index(const struct CustomData *data, int type);
+int CustomData_get_clone_layer_index(const struct CustomData *data, int type);
+int CustomData_get_mask_layer_index(const struct CustomData *data, int type);
int CustomData_get_active_layer(const struct CustomData *data, int type);
int CustomData_get_render_layer(const struct CustomData *data, int type);
+int CustomData_get_clone_layer(const struct CustomData *data, int type);
+int CustomData_get_mask_layer(const struct CustomData *data, int type);
/* copies the data from source to the data element at index in the first
* layer of type
@@ -227,10 +231,14 @@ void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, voi
/* sets the nth layer of type as active */
void CustomData_set_layer_active(struct CustomData *data, int type, int n);
void CustomData_set_layer_render(struct CustomData *data, int type, int n);
+void CustomData_set_layer_clone(struct CustomData *data, int type, int n);
+void CustomData_set_layer_mask(struct CustomData *data, int type, int n);
/* same as above but works with an index from CustomData_get_layer_index */
void CustomData_set_layer_active_index(struct CustomData *data, int type, int n);
void CustomData_set_layer_render_index(struct CustomData *data, int type, int n);
+void CustomData_set_layer_clone_index(struct CustomData *data, int type, int n);
+void CustomData_set_layer_mask_index(struct CustomData *data, int type, int n);
/* adds flag to the layer flags */
void CustomData_set_layer_flag(struct CustomData *data, int type, int flag);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index e93266c85f3..f7fca8c1412 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -606,7 +606,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
{
const LayerTypeInfo *typeInfo;
CustomDataLayer *layer, *newlayer;
- int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0;
+ int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0;
for(i = 0; i < source->totlayer; ++i) {
layer = &source->layers[i];
@@ -618,6 +618,8 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
number = 0;
lastactive = layer->active;
lastrender = layer->active_rnd;
+ lastclone = layer->active_clone;
+ lastmask = layer->active_mask;
lasttype = type;
}
else
@@ -637,6 +639,8 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
if(newlayer) {
newlayer->active = lastactive;
newlayer->active_rnd = lastrender;
+ newlayer->active_clone = lastclone;
+ newlayer->active_mask = lastmask;
}
}
}
@@ -736,6 +740,28 @@ int CustomData_get_render_layer_index(const CustomData *data, int type)
return -1;
}
+int CustomData_get_clone_layer_index(const CustomData *data, int type)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ return i + data->layers[i].active_clone;
+
+ return -1;
+}
+
+int CustomData_get_mask_layer_index(const CustomData *data, int type)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ return i + data->layers[i].active_mask;
+
+ return -1;
+}
+
int CustomData_get_active_layer(const CustomData *data, int type)
{
int i;
@@ -758,6 +784,27 @@ int CustomData_get_render_layer(const CustomData *data, int type)
return -1;
}
+int CustomData_get_clone_layer(const CustomData *data, int type)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ return data->layers[i].active_clone;
+
+ return -1;
+}
+
+int CustomData_get_mask_layer(const CustomData *data, int type)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ return data->layers[i].active_mask;
+
+ return -1;
+}
void CustomData_set_layer_active(CustomData *data, int type, int n)
{
@@ -777,6 +824,24 @@ void CustomData_set_layer_render(CustomData *data, int type, int n)
data->layers[i].active_rnd = n;
}
+void CustomData_set_layer_clone(CustomData *data, int type, int n)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ data->layers[i].active_clone = n;
+}
+
+void CustomData_set_layer_mask(CustomData *data, int type, int n)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ data->layers[i].active_mask = n;
+}
+
/* for using with an index from CustomData_get_active_layer_index and CustomData_get_render_layer_index */
void CustomData_set_layer_active_index(CustomData *data, int type, int n)
{
@@ -796,6 +861,23 @@ void CustomData_set_layer_render_index(CustomData *data, int type, int n)
data->layers[i].active_rnd = n-i;
}
+void CustomData_set_layer_clone_index(CustomData *data, int type, int n)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ data->layers[i].active_clone = n-i;
+}
+
+void CustomData_set_layer_mask_index(CustomData *data, int type, int n)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ data->layers[i].active_mask = n-i;
+}
void CustomData_set_layer_flag(struct CustomData *data, int type, int flag)
{
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index fd3f6e926b9..5612f56fee8 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -446,6 +446,8 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_GEN_SKELETON 2085
#define B_RETARGET_SKELETON 2086
+#define B_SETTFACE_CLONE 2087
+#define B_SETTFACE_MASK 2088
/* *********************** */
#define B_VGROUPBUTS 2100
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 6c098e220bb..e6b18641d2a 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -37,6 +37,8 @@ typedef struct CustomDataLayer {
int flag; /* general purpose flag */
int active; /* number of the active layer of this type */
int active_rnd; /* number of the layer to render*/
+ int active_clone; /* number of the layer to render*/
+ int active_mask; /* number of the layer to render*/
char pad[4];
char name[32]; /* layer name */
void *data; /* layer data */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 77cfaf10ac1..8b264602fee 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -347,8 +347,7 @@ typedef struct ImagePaintSettings {
short flag, tool;
/* for projection painting only - todo - use flags */
- char seam_bleed,normal_angle;
- short clone_layer;
+ short seam_bleed,normal_angle;
} ImagePaintSettings;
typedef struct ParticleBrushData {
@@ -806,8 +805,10 @@ typedef struct Scene {
#define IMAGEPAINT_PROJECT_DISABLE 8 /* Non projection 3D painting */
#define IMAGEPAINT_PROJECT_XRAY 16
#define IMAGEPAINT_PROJECT_BACKFACE 32
-#define IMAGEPAINT_PROJECT_CLONE_LAYER 64
-#define IMAGEPAINT_PROJECT_FLAT 128
+#define IMAGEPAINT_PROJECT_FLAT 64
+#define IMAGEPAINT_PROJECT_LAYER_CLONE 128
+#define IMAGEPAINT_PROJECT_LAYER_MASK 256
+#define IMAGEPAINT_PROJECT_LAYER_MASK_INV 512
/* toolsettings->uvcalc_flag */
#define UVCALC_FILLHOLES 1
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 46359aa2707..1157dc7b26a 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -184,7 +184,7 @@
static float editbutweight= 1.0;
float editbutvweight= 1;
-static int actmcol= 0, acttface= 0, acttface_rnd = 0, actmcol_rnd = 0;
+static int actmcol= 0, acttface= 0, acttface_rnd = 0, acttface_clone = 0, acttface_mask = 0, actmcol_rnd = 0;
extern ListBase editNurb;
@@ -802,9 +802,9 @@ static void delete_customdata_layer(void *data1, void *data2)
static int customdata_buttons(
uiBlock *block, Mesh *me, CustomData *data,
- int type, int *activep, int *renderp,
- int setevt, int setevt_rnd, int newevt,
- char *label, char *shortlabel, char *browsetip, char *browsetip_rnd,
+ int type, int *activep, int *renderp, int *clonep, int *maskp,
+ int setevt, int setevt_rnd, int setevt_clone, int setevt_mask, int newevt,
+ char *label, char *shortlabel, char *browsetip, char *browsetip_rnd, char *browsetip_clone, char *browsetip_mask,
char *newtip, char *deltip, int x, int y)
{
CustomDataLayer *layer;
@@ -828,12 +828,27 @@ static int customdata_buttons(
layer= &data->layers[i];
if(layer->type == type) {
+ int xi = 0;
*activep= layer->active + 1;
*renderp= layer->active_rnd + 1;
+ if (clonep) *clonep= layer->active_clone + 1;
+ if (maskp) *maskp= layer->active_mask + 1;
+
uiDefIconButI(block, ROW, setevt, ICON_VIEW3D, x,y,25,19, activep, 1.0, count, 0, 0, browsetip);
uiDefIconButI(block, ROW, setevt_rnd, ICON_SCENE, x+25,y,25,19, renderp, 1.0, count, 0, 0, browsetip_rnd);
- but=uiDefBut(block, TEX, setevt, "", x+50,y,145,19, layer->name, 0.0, 31.0, 0, 0, label);
+
+ if (clonep) {
+ uiDefIconButI(block, ROW, setevt_clone, ICON_TEXTURE, x+50,y,25,19, clonep, 1.0, count, 0, 0, browsetip_clone);
+ xi += 25;
+ }
+
+ if (maskp) {
+ uiDefIconButI(block, ROW, setevt_mask, ICON_PAINT, x+50+xi,y,25,19, maskp, 1.0, count, 0, 0, browsetip_mask);
+ xi += 25;
+ }
+
+ but=uiDefBut(block, TEX, setevt, "", x+50+xi,y,145-xi,19, layer->name, 0.0, 31.0, 0, 0, label);
uiButSetFunc(but, verify_customdata_name_func, data, layer);
but= uiDefIconBut(block, BUT, B_NOP, VICON_X, x+195,y,25,19, NULL, 0.0, 0.0, 0.0, 0.0, deltip);
uiButSetFunc(but, delete_customdata_layer, me, layer);
@@ -902,14 +917,14 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
uiBlockEndAlign(block);
fdata= (G.obedit)? &G.editMesh->fdata: &me->fdata;
- yco= customdata_buttons(block, me, fdata, CD_MTFACE, &acttface, &acttface_rnd,
- B_SETTFACE, B_SETTFACE_RND, B_NEWTFACE, "UV Texture", "UV Texture:",
- "Set active UV texture", "Set rendering UV texture", "Creates a new UV texture layer",
+ yco= customdata_buttons(block, me, fdata, CD_MTFACE, &acttface, &acttface_rnd, (G.f & G_TEXTUREPAINT ? &acttface_clone : NULL), (G.f & G_TEXTUREPAINT ? &acttface_mask : NULL),
+ B_SETTFACE, B_SETTFACE_RND, B_SETTFACE_CLONE, B_SETTFACE_MASK, B_NEWTFACE, "UV Texture", "UV Texture:",
+ "Set active UV texture", "Set rendering UV texture", "Set the layer used for texturepaint cloning", "Set the layer used for texturepaint masking", "Creates a new UV texture layer",
"Removes the current UV texture layer", 190, 130);
- yco= customdata_buttons(block, me, fdata, CD_MCOL, &actmcol, &actmcol_rnd,
- B_SETMCOL, B_SETMCOL_RND, B_NEWMCOL, "Vertex Color", "Vertex Color:",
- "Sets active vertex color layer", "Sets rendering vertex color layer", "Creates a new vertex color layer",
+ yco= customdata_buttons(block, me, fdata, CD_MCOL, &actmcol, &actmcol_rnd, NULL, NULL,
+ B_SETMCOL, B_SETMCOL_RND, B_NOP, B_NOP, B_NEWMCOL, "Vertex Color", "Vertex Color:",
+ "Sets active vertex color layer", "Sets rendering vertex color layer", "", "", "Creates a new vertex color layer",
"Removes the current vertex color layer", 190, yco-5);
if(yco < 0)
@@ -4964,7 +4979,22 @@ void do_meshbuts(unsigned short event)
allqueue(REDRAWBUTSEDIT, 0);
}
break;
-
+ case B_SETTFACE_CLONE:
+ if (G.obedit || me) {
+ CustomData *fdata= (G.obedit)? &em->fdata: &me->fdata;
+ CustomData_set_layer_clone(fdata, CD_MTFACE, acttface_clone-1);
+ BIF_undo_push("Set Clone UV Texture");
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ break;
+ case B_SETTFACE_MASK:
+ if (G.obedit || me) {
+ CustomData *fdata= (G.obedit)? &em->fdata: &me->fdata;
+ CustomData_set_layer_mask(fdata, CD_MTFACE, acttface_mask-1);
+ BIF_undo_push("Set Mask UV Texture");
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ break;
case B_FLIPNORM:
if(G.obedit) {
flip_editnormals();
@@ -6387,6 +6417,12 @@ static void editing_panel_mesh_paint(void)
uiDefButC(block, NUM, B_NOP, "Bleed: ", xco+10,yco-85,butw,19, &settings->imapaint.seam_bleed, 0.0, 8.0, 0, 0, "Extend paint beyond the faces UVs to reduce seams (in pixels, slower)");
uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_LAYER_MASK, B_NOP, "Layer Mask", xco+10,yco-110,butw-30,19, &settings->imapaint.flag, 0, 0, 0, 0, "Set the mask layer from the UV layer buttons");
+ uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_LAYER_MASK_INV, B_NOP, "Inv", xco+10 + butw-30,yco-110,30,19, &settings->imapaint.flag, 0, 0, 0, 0, "Invert the mask");
+ uiBlockEndAlign(block);
+
}
uiBlockBeginAlign(block);
@@ -6404,33 +6440,11 @@ static void editing_panel_mesh_paint(void)
yco -= 110;
if (settings->imapaint.tool == PAINT_TOOL_CLONE) {
- Object *ob = OBACT;
- if (ob) {
- Mesh *me = ob->data;
- int layercount = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
- if (layercount>1 && layercount < 12) { /* could allow any number but limit of 11 means no malloc needed */
-
- butw = 80;
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_CLONE_LAYER, B_REDR, "Clone Layer", 0,yco,butw,20, &settings->imapaint.flag, 0, 0, 0, 0, "Use another UV layer as clone source, otherwise use 3D the cursor as the source");
-
- if (settings->imapaint.flag & IMAGEPAINT_PROJECT_CLONE_LAYER) {
- char str_menu[384], *str_pt; /*384 allows for 11 layers */
-
- if (settings->imapaint.clone_layer >= layercount) {
- settings->imapaint.clone_layer = 0;
- }
-
-
-
- /*str_pt = (char *)MEM_mallocN(layercount*40 , "uvmenu"); str[0]='\0';*/
- str_pt = str_menu;
- str_pt[0]='\0';
- mesh_layers_menu_concat(&me->fdata, CD_MTFACE, str_pt);
- uiDefButI(block, MENU, B_NOP, str_menu ,butw,yco,(180-butw) + 20,20, &settings->imapaint.clone_layer, 0, 0, 0, 0, "Active UV Layer for editing");
- }
- uiBlockEndAlign(block);
- }
+ if ((settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)==0) {
+ butw = 130;
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_LAYER_CLONE, B_REDR, "Clone from Layer", 0,yco,butw,20, &settings->imapaint.flag, 0, 0, 0, 0, "Use another UV layer as clone source, otherwise use 3D the cursor as the source");
+ uiBlockEndAlign(block);
}
} else {
uiBlockSetCol(block, TH_BUT_SETTING2);
diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c
index 9cb665bd8a9..d3efeba772c 100644
--- a/source/blender/src/imagepaint.c
+++ b/source/blender/src/imagepaint.c
@@ -218,6 +218,7 @@ typedef struct ProjPaintState {
MFace *dm_mface;
MTFace *dm_mtface;
MTFace *dm_mtface_clone; /* other UV layer, use for cloning between layers */
+ MTFace *dm_mtface_mask;
/* projection painting only */
MemArena *arena_mt[BLENDER_MAX_THREADS];/* for multithreading, the first item is sometimes used for non threaded cases too */
@@ -245,11 +246,15 @@ typedef struct ProjPaintState {
float screen_height;
/* options for projection painting */
+ int do_layer_clone;
+ int do_layer_mask;
+ int do_layer_mask_inv;
+
short do_occlude; /* Use raytraced occlusion? - ortherwise will paint right through to the back*/
short do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
short do_mask_normal; /* mask out pixels based on their normals */
float normal_angle; /* what angle to mask at*/
-
+
short is_ortho;
short is_airbrush; /* only to avoid using (ps.brush->flag & BRUSH_AIRBRUSH) */
short is_texbrush; /* only to avoid running */
@@ -258,7 +263,6 @@ typedef struct ProjPaintState {
#endif
/* clone vars */
float cloneOffset[2];
- int clone_layer; /* -1 when not in use */
float projectMat[4][4]; /* Projection matrix, use for getting screen coords */
float viewMat[4][4];
@@ -1292,6 +1296,36 @@ static void screen_px_from_persp(
VecWeightf(pixelScreenCo, v1co, v2co, v3co, w);
}
+static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3], int side, unsigned char rgba_ub[4], float rgba_f[4])
+{
+ float *uvCo1, *uvCo2, *uvCo3;
+ float uv_other[2], x, y;
+
+ uvCo1 = (float *)tf_other->uv[0];
+ if (side==1) {
+ uvCo2 = (float *)tf_other->uv[2];
+ uvCo3 = (float *)tf_other->uv[3];
+ }
+ else {
+ uvCo2 = (float *)tf_other->uv[1];
+ uvCo3 = (float *)tf_other->uv[2];
+ }
+
+ Vec2Weightf(uv_other, uvCo1, uvCo2, uvCo3, w);
+
+ /* use */
+ uvco_to_wrapped_pxco(uv_other, ibuf_other->x, ibuf_other->y, &x, &y);
+
+
+ if (ibuf_other->rect_float) { /* from float to float */
+ bilinear_interpolation_color(ibuf_other, NULL, rgba_f, x, y);
+ }
+ else { /* from char to float */
+ bilinear_interpolation_color(ibuf_other, rgba_ub, NULL, x, y);
+ }
+
+}
+
/* run this outside project_paint_uvpixel_init since pixels with mask 0 dont need init */
float project_paint_uvpixel_mask(
const ProjPaintState *ps,
@@ -1301,6 +1335,40 @@ float project_paint_uvpixel_mask(
{
float mask, mask_angle;
+ /* Image Mask */
+ if (ps->do_layer_mask) {
+ /* another UV layers image is masking this one's */
+ ImBuf *ibuf_other;
+ const MTFace *tf_other = ps->dm_mtface_mask + face_index;
+
+ if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf((Image *)tf_other->tpage, NULL))) {
+ /* BKE_image_get_ibuf - TODO - this may be slow */
+ unsigned char rgba_ub[4];
+ float rgba_f[4];
+
+ project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, rgba_f);
+
+ if (ibuf_other->rect_float) { /* from float to float */
+ mask = ((rgba_f[0]+rgba_f[1]+rgba_f[2])/3.0f) * rgba_f[3];
+ }
+ else { /* from char to float */
+ mask = ((rgba_ub[0]+rgba_ub[1]+rgba_ub[2])/(256*3.0f)) * (rgba_ub[3]/256.0f);
+ }
+
+ if (!ps->do_layer_mask_inv) /* matching the gimps layer mask black/white rules, white==full opacity */
+ mask = (1.0f - mask);
+
+ if (mask == 0.0f) {
+ return 0.0f;
+ }
+ }
+ else {
+ return 0.0f;
+ }
+ } else {
+ mask = 1.0f;
+ }
+
/* calculate mask */
if (ps->do_mask_normal) {
MFace *mf = ps->dm_mface + face_index;
@@ -1346,12 +1414,13 @@ float project_paint_uvpixel_mask(
angle = NormalizedVecAngle2(viewDirPersp, no);
}
- /*if (angle >= (M_PI_2 / 90) * ps->normal_angle) {
+ if (angle >= (M_PI_2 / 90) * ps->normal_angle) {
return 0.0f;
}
- else {*/
+ else {
+ float mask_no;
#if 0
- mask = 1.0f - (angle / PI_80_DEG); /* map angle to 1.0-facing us, 0.0 right angles to the view direction */
+ mask *= 1.0f - (angle / PI_80_DEG); /* map angle to 1.0-facing us, 0.0 right angles to the view direction */
#endif
/* trickier method that clips the normal so its more useful */
@@ -1361,15 +1430,14 @@ float project_paint_uvpixel_mask(
/*printf("normal_angle : %f \n" ,ps->normal_angle);
printf("mask_angle : %f \n" ,mask_angle);*/
- mask = (angle / mask_angle); /* map angle to 1.0-facing us, 0.0 right angles to the view direction */
- mask = (1.0f - (mask * mask * mask)) * 1.4f;
- if (mask > 1.0f) {
- mask = 1.0f;
+ mask_no = (angle / mask_angle); /* map angle to 1.0-facing us, 0.0 right angles to the view direction */
+ mask_no = (1.0f - (mask_no * mask_no * mask_no)) * 1.4f;
+ if (mask_no > 1.0f) {
+ mask_no = 1.0f;
}
- /*}*/
+
+ mask *= mask_no;
}
- else {
- mask = 1.0f;
}
if (ps->is_airbrush==0) {
@@ -1438,7 +1506,6 @@ static ProjPixel *project_paint_uvpixel_init(
/* which bounding box cell are we in?, needed for undo */
projPixel->bb_cell_index = ((int)(((float)x_px/(float)ibuf->x) * PROJ_BOUNDBOX_DIV)) + ((int)(((float)y_px/(float)ibuf->y) * PROJ_BOUNDBOX_DIV)) * PROJ_BOUNDBOX_DIV ;
-
/* done with view3d_project_float inline */
if (ps->tool==PAINT_TOOL_CLONE) {
if (ps->dm_mtface_clone) {
@@ -1448,48 +1515,24 @@ static ProjPixel *project_paint_uvpixel_init(
if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf((Image *)tf_other->tpage, NULL))) {
/* BKE_image_get_ibuf - TODO - this may be slow */
- float *uvCo1, *uvCo2, *uvCo3;
- float uv_other[2], x, y;
-
- uvCo1 = (float *)tf_other->uv[0];
- if (side==1) {
- uvCo2 = (float *)tf_other->uv[2];
- uvCo3 = (float *)tf_other->uv[3];
- }
- else {
- uvCo2 = (float *)tf_other->uv[1];
- uvCo3 = (float *)tf_other->uv[2];
- }
-
- Vec2Weightf(uv_other, uvCo1, uvCo2, uvCo3, w);
-
- /* use */
- uvco_to_wrapped_pxco(uv_other, ibuf->x, ibuf->y, &x, &y);
-
- if (x < 0.0f) x += 1.0f;
- if (y < 0.0f) y += 1.0f;
-
- x = x * ibuf_other->x - 0.5f;
- y = y * ibuf_other->y - 0.5f;
-
if (ibuf->rect_float) {
if (ibuf_other->rect_float) { /* from float to float */
- bilinear_interpolation_color(ibuf_other, NULL, ((ProjPixelClone *)projPixel)->clonepx.f, x, y);
+ project_face_pixel(tf_other, ibuf_other, w, side, NULL, ((ProjPixelClone *)projPixel)->clonepx.f);
}
else { /* from char to float */
unsigned char rgba_ub[4];
- bilinear_interpolation_color(ibuf_other, rgba_ub, NULL, x, y);
+ project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, NULL);
IMAPAINT_CHAR_RGBA_TO_FLOAT(((ProjPixelClone *)projPixel)->clonepx.f, rgba_ub);
}
}
else {
if (ibuf_other->rect_float) { /* float to char */
float rgba[4];
- bilinear_interpolation_color(ibuf_other, NULL, rgba, x, y);
+ project_face_pixel(tf_other, ibuf_other, w, side, NULL, rgba);
IMAPAINT_FLOAT_RGBA_TO_CHAR(((ProjPixelClone *)projPixel)->clonepx.ch, rgba)
}
else { /* char to char */
- bilinear_interpolation_color(ibuf_other, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL, x, y);
+ project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL);
}
}
}
@@ -2853,16 +2896,35 @@ static void project_paint_begin(ProjPaintState *ps, short mval[2])
/* use clone mtface? */
- if ( ps->tool != PAINT_TOOL_CLONE ||
- ps->clone_layer==-1 ||
- ps->clone_layer >= CustomData_number_of_layers(&ps->dm->faceData, CD_MTFACE)
- ) {
- ps->dm_mtface_clone = NULL;
+
+ /* Note, use the original mesh for getting the clone and mask layer index
+ * this avoids re-generating the derived mesh just to get the new index */
+ if (ps->do_layer_clone) {
+ //int layer_num = CustomData_get_clone_layer(&ps->dm->faceData, CD_MTFACE);
+ int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
+ if (layer_num != -1)
+ ps->dm_mtface_clone = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
+
+ if (ps->dm_mtface_clone==NULL || ps->dm_mtface_clone==ps->dm_mtface) {
+ ps->do_layer_clone = 0;
+ ps->dm_mtface_clone= NULL;
+ }
}
- else {
- ps->dm_mtface_clone = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, ps->clone_layer);
+
+ if (ps->do_layer_mask) {
+ //int layer_num = CustomData_get_mask_layer(&ps->dm->faceData, CD_MTFACE);
+ int layer_num = CustomData_get_mask_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
+ if (layer_num != -1)
+ ps->dm_mtface_mask = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
+
+ if (ps->dm_mtface_mask==NULL || ps->dm_mtface_mask==ps->dm_mtface) {
+ ps->do_layer_mask = 0;
+ ps->dm_mtface_mask = NULL;
+ }
}
+
+
ps->viewDir[0] = 0.0f;
ps->viewDir[1] = 0.0f;
ps->viewDir[2] = 1.0f;
@@ -4458,12 +4520,13 @@ void imagepaint_paint(short mousebutton, short texpaint)
ps.do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? 0 : 1;
ps.do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? 0 : 1;
ps.do_mask_normal = (settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT) ? 0 : 1;;
- if (settings->imapaint.flag & IMAGEPAINT_PROJECT_CLONE_LAYER) {
- ps.clone_layer = settings->imapaint.clone_layer;
- }
- else {
- ps.clone_layer = -1;
- }
+
+ if (ps.tool == PAINT_TOOL_CLONE)
+ ps.do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE);
+
+ ps.do_layer_mask = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_MASK) ? 1 : 0;
+ ps.do_layer_mask_inv = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_MASK_INV) ? 1 : 0;
+
#ifndef PROJ_DEBUG_NOSEAMBLEED
ps.seam_bleed_px = settings->imapaint.seam_bleed; /* pixel num to bleed */