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:
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt2
-rw-r--r--source/blender/editors/sculpt_paint/SConscript5
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c16
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve.c18
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c15
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c146
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c10
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c36
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c77
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c5
14 files changed, 224 insertions, 120 deletions
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 0fa5f2d9837..46753df4e13 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -23,7 +23,7 @@ set(INC
../uvedit
../../blenkernel
../../blenlib
- ../../blenfont
+ ../../blentranslation
../../bmesh
../../gpu
../../imbuf
diff --git a/source/blender/editors/sculpt_paint/SConscript b/source/blender/editors/sculpt_paint/SConscript
index 233f562fcc7..52fab472189 100644
--- a/source/blender/editors/sculpt_paint/SConscript
+++ b/source/blender/editors/sculpt_paint/SConscript
@@ -29,7 +29,8 @@ Import ('env')
sources = env.Glob('*.c')
-defs = env['BF_GL_DEFINITIONS']
+defs = []
+defs += env['BF_GL_DEFINITIONS']
incs = [
'#/intern/guardedalloc',
@@ -37,9 +38,9 @@ incs = [
'#/intern/glew-mx',
'../include',
'../uvedit',
- '../../blenfont',
'../../blenkernel',
'../../blenlib',
+ '../../blentranslation',
'../../bmesh',
'../../gpu',
'../../imbuf',
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index e4cad389004..e19756c6a35 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -644,9 +644,9 @@ static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush,
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
if (primary)
- glTranslatef(brush->stencil_pos[0], brush->stencil_pos[1], 0);
+ glTranslate2fv(brush->stencil_pos);
else
- glTranslatef(brush->mask_stencil_pos[0], brush->mask_stencil_pos[1], 0);
+ glTranslate2fv(brush->mask_stencil_pos);
glRotatef(RAD2DEGF(mtex->rot), 0, 0, 1);
glMatrixMode(GL_TEXTURE);
}
@@ -725,7 +725,7 @@ static void paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush,
do_pop = true;
glPushMatrix();
glLoadIdentity();
- glTranslatef(center[0], center[1], 0);
+ glTranslate2fv(center);
glScalef(ups->size_pressure_value, ups->size_pressure_value, 1);
glTranslatef(-center[0], -center[1], 0);
}
@@ -756,7 +756,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
ViewContext *vc, int x, int y, float zoom, PaintMode mode)
{
/* color means that primary brush texture is colured and secondary is used for alpha/mask control */
- bool col = ELEM(mode, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D, PAINT_VERTEX) ? true : false;
+ bool col = ELEM(mode, ePaintTextureProjective, ePaintTexture2D, ePaintVertex) ? true : false;
OverlayControlFlags flags = BKE_paint_get_overlay_flags();
/* save lots of GL state
* TODO: check on whether all of these are needed? */
@@ -782,7 +782,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
}
else {
- if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY) && (mode != PAINT_WEIGHT))
+ if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY) && (mode != ePaintWeight))
paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, false, true);
if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR))
paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
@@ -958,7 +958,7 @@ static void paint_cursor_on_hit(UnifiedPaintSettings *ups, Brush *brush, ViewCon
static bool ommit_cursor_drawing(Paint *paint, PaintMode mode, Brush *brush)
{
if (paint->flags & PAINT_SHOW_BRUSH) {
- if (ELEM(mode, PAINT_TEXTURE_2D, PAINT_TEXTURE_PROJECTIVE) && brush->imagepaint_tool == PAINT_TOOL_FILL) {
+ if (ELEM(mode, ePaintTexture2D, ePaintTextureProjective) && brush->imagepaint_tool == PAINT_TOOL_FILL) {
return true;
}
return false;
@@ -1014,7 +1014,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
/* TODO: as sculpt and other paint modes are unified, this
* special mode of drawing will go away */
- if ((mode == PAINT_SCULPT) && vc.obact->sculpt) {
+ if ((mode == ePaintSculpt) && vc.obact->sculpt) {
float location[3];
int pixel_radius;
bool hit;
@@ -1056,7 +1056,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha);
/* draw brush outline */
- glTranslatef(translation[0], translation[1], 0);
+ glTranslate2fv(translation);
/* draw an inner brush */
if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) {
diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c
index ebe5268ec5c..2f27db835f5 100644
--- a/source/blender/editors/sculpt_paint/paint_curve.c
+++ b/source/blender/editors/sculpt_paint/paint_curve.c
@@ -134,12 +134,12 @@ static void paintcurve_undo_begin(bContext *C, wmOperator *op, PaintCurve *pc)
UndoCurve *uc;
switch (mode) {
- case PAINT_TEXTURE_2D:
- case PAINT_TEXTURE_PROJECTIVE:
+ case ePaintTexture2D:
+ case ePaintTextureProjective:
undo_stack_id = UNDO_PAINT_IMAGE;
break;
- case PAINT_SCULPT:
+ case ePaintSculpt:
undo_stack_id = UNDO_PAINT_MESH;
break;
@@ -737,17 +737,17 @@ static int paintcurve_draw_exec(bContext *C, wmOperator *UNUSED(op))
const char *name;
switch (mode) {
- case PAINT_TEXTURE_2D:
- case PAINT_TEXTURE_PROJECTIVE:
+ case ePaintTexture2D:
+ case ePaintTextureProjective:
name = "PAINT_OT_image_paint";
break;
- case PAINT_WEIGHT:
+ case ePaintWeight:
name = "PAINT_OT_weight_paint";
break;
- case PAINT_VERTEX:
+ case ePaintVertex:
name = "PAINT_OT_vertex_paint";
break;
- case PAINT_SCULPT:
+ case ePaintSculpt:
name = "SCULPT_OT_brush_stroke";
break;
default:
@@ -777,7 +777,7 @@ static int paintcurve_cursor_invoke(bContext *C, wmOperator *UNUSED(op), const w
PaintMode mode = BKE_paintmode_get_active_from_context(C);
switch (mode) {
- case PAINT_TEXTURE_2D:
+ case ePaintTexture2D:
{
ARegion *ar = CTX_wm_region(C);
SpaceImage *sima = CTX_wm_space_image(C);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 64e0aa822df..f0c9c023876 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -1045,8 +1045,9 @@ static void toggle_paint_cursor(bContext *C, int enable)
* purpose is to make sure the paint cursor is shown if paint
* mode is enabled in the image editor. the paint poll will
* ensure that the cursor is hidden when not in paint mode */
-void ED_space_image_paint_update(wmWindowManager *wm, ToolSettings *settings)
+void ED_space_image_paint_update(wmWindowManager *wm, Scene *scene)
{
+ ToolSettings *settings = scene->toolsettings;
wmWindow *win;
ScrArea *sa;
ImagePaintSettings *imapaint = &settings->imapaint;
@@ -1059,7 +1060,7 @@ void ED_space_image_paint_update(wmWindowManager *wm, ToolSettings *settings)
enabled = true;
if (enabled) {
- BKE_paint_init(&settings->unified_paint_settings, &imapaint->paint, PAINT_CURSOR_TEXTURE_PAINT);
+ BKE_paint_init(scene, ePaintTexture2D, PAINT_CURSOR_TEXTURE_PAINT);
paint_cursor_start_explicit(&imapaint->paint, wm, image_paint_poll);
}
@@ -1212,7 +1213,7 @@ static int sample_color_exec(bContext *C, wmOperator *op)
RNA_int_get_array(op->ptr, "location", location);
use_palette = RNA_boolean_get(op->ptr, "palette");
- paint_sample_color(C, ar, location[0], location[1], mode == PAINT_TEXTURE_PROJECTIVE, use_palette);
+ paint_sample_color(C, ar, location[0], location[1], mode == ePaintTextureProjective, use_palette);
if (show_cursor) {
paint->flags |= PAINT_SHOW_BRUSH;
@@ -1250,7 +1251,7 @@ static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event
RNA_int_set_array(op->ptr, "location", event->mval);
- paint_sample_color(C, ar, event->mval[0], event->mval[1], mode == PAINT_TEXTURE_PROJECTIVE, false);
+ paint_sample_color(C, ar, event->mval[0], event->mval[1], mode == ePaintTextureProjective, false);
WM_cursor_modal_set(win, BC_EYEDROPPER_CURSOR);
WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
@@ -1289,7 +1290,7 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
RNA_int_set_array(op->ptr, "location", event->mval);
- paint_sample_color(C, ar, event->mval[0], event->mval[1], mode == PAINT_TEXTURE_PROJECTIVE, false);
+ paint_sample_color(C, ar, event->mval[0], event->mval[1], mode == ePaintTextureProjective, false);
WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
break;
}
@@ -1298,7 +1299,7 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val == KM_PRESS) {
ARegion *ar = CTX_wm_region(C);
RNA_int_set_array(op->ptr, "location", event->mval);
- paint_sample_color(C, ar, event->mval[0], event->mval[1], mode == PAINT_TEXTURE_PROJECTIVE, true);
+ paint_sample_color(C, ar, event->mval[0], event->mval[1], mode == ePaintTextureProjective, true);
if (!data->sample_palette) {
data->sample_palette = true;
sample_color_update_header(data, C);
@@ -1416,7 +1417,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
ob->mode |= mode_flag;
- BKE_paint_init(&scene->toolsettings->unified_paint_settings, &imapaint->paint, PAINT_CURSOR_TEXTURE_PAINT);
+ BKE_paint_init(scene, ePaintTextureProjective, PAINT_CURSOR_TEXTURE_PAINT);
if (U.glreslimit != 0)
GPU_free_images();
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 03a96fb149a..c5a066e9b14 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -1601,6 +1601,7 @@ void paint_2d_gradient_fill(
break;
}
case BRUSH_GRADIENT_RADIAL:
+ default:
{
f = len_v2(p) / line_len;
break;
@@ -1629,6 +1630,7 @@ void paint_2d_gradient_fill(
break;
}
case BRUSH_GRADIENT_RADIAL:
+ default:
{
f = len_v2(p) / line_len;
break;
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index d54db048faf..565f8a51610 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -49,7 +49,7 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
-#include "BLF_translation.h"
+#include "BLT_translation.h"
#include "IMB_imbuf.h"
@@ -298,6 +298,7 @@ typedef struct ProjPaintState {
float cloneOffset[2];
float projectMat[4][4]; /* Projection matrix, use for getting screen coords */
+ float projectMatInv[4][4]; /* inverse of projectMat */
float viewDir[3]; /* View vector, use for do_backfacecull and for ray casting with an ortho viewport */
float viewPos[3]; /* View location in object relative 3D space, so can compare to verts */
float clipsta, clipend;
@@ -1247,6 +1248,55 @@ static void screen_px_from_persp(
}
+/**
+ * Set a direction vector based on a screen location.
+ * (use for perspective view, else we can simply use `ps->viewDir`)
+ *
+ * Similar functionality to #ED_view3d_win_to_vector
+ *
+ * \param r_dir: Resulting direction (length is undefined).
+ */
+static void screen_px_to_vector_persp(
+ int winx, int winy, const float projmat_inv[4][4], const float view_pos[3],
+ const float co_px[2],
+ float r_dir[3])
+{
+ r_dir[0] = 2.0f * (co_px[0] / winx) - 1.0f;
+ r_dir[1] = 2.0f * (co_px[1] / winy) - 1.0f;
+ r_dir[2] = -0.5f;
+ mul_project_m4_v3((float(*)[4])projmat_inv, r_dir);
+ sub_v3_v3(r_dir, view_pos);
+}
+
+/**
+ * Special function to return the factor to a point along a line in pixel space.
+ *
+ * This is needed since we can't use #line_point_factor_v2 for perspective screen-space coords.
+ *
+ * \param p: 2D screen-space location.
+ * \param v1, v2: 3D object-space locations.
+ */
+static float screen_px_line_point_factor_v2_persp(
+ const ProjPaintState *ps,
+ const float p[2],
+ const float v1[3], const float v2[3])
+{
+ const float zero[3] = {0};
+ float v1_proj[3], v2_proj[3];
+ float dir[3];
+
+ screen_px_to_vector_persp(ps->winx, ps->winy, ps->projectMatInv, ps->viewPos, p, dir);
+
+ sub_v3_v3v3(v1_proj, v1, ps->viewPos);
+ sub_v3_v3v3(v2_proj, v2, ps->viewPos);
+
+ project_plane_v3_v3v3(v1_proj, v1_proj, dir);
+ project_plane_v3_v3v3(v2_proj, v2_proj, dir);
+
+ return line_point_factor_v2(zero, v1_proj, v2_proj);
+}
+
+
static void project_face_pixel(
const float *lt_tri_uv[3], ImBuf *ibuf_other, const float w[3],
unsigned char rgba_ub[4], float rgba_f[4])
@@ -2038,16 +2088,16 @@ static void project_bucket_clip_face(
int inside_bucket_flag = 0;
int inside_face_flag = 0;
int flip;
- bool colinear = false;
+ bool collinear = false;
float bucket_bounds_ss[4][2];
- /* detect pathological case where face the three vertices are almost colinear in screen space.
+ /* detect pathological case where face the three vertices are almost collinear in screen space.
* mostly those will be culled but when flood filling or with smooth shading it's a possibility */
if (dist_squared_to_line_v2(v1coSS, v2coSS, v3coSS) < 0.5f ||
dist_squared_to_line_v2(v2coSS, v3coSS, v1coSS) < 0.5f)
{
- colinear = true;
+ collinear = true;
}
/* get the UV space bounding box */
@@ -2077,7 +2127,7 @@ static void project_bucket_clip_face(
return;
}
/* handle pathological case here, no need for further intersections below since tringle area is almost zero */
- if (colinear) {
+ if (collinear) {
int flag;
(*tot) = 0;
@@ -2680,8 +2730,15 @@ static void project_paint_face_init(
line_clip_rect2f(clip_rect, bucket_bounds, vCoSS[fidx1], vCoSS[fidx2], bucket_clip_edges[0], bucket_clip_edges[1]))
{
if (len_squared_v2v2(vCoSS[fidx1], vCoSS[fidx2]) > FLT_EPSILON) { /* avoid div by zero */
- fac1 = line_point_factor_v2(bucket_clip_edges[0], vCoSS[fidx1], vCoSS[fidx2]);
- fac2 = line_point_factor_v2(bucket_clip_edges[1], vCoSS[fidx1], vCoSS[fidx2]);
+
+ if (is_ortho) {
+ fac1 = line_point_factor_v2(bucket_clip_edges[0], vCoSS[fidx1], vCoSS[fidx2]);
+ fac2 = line_point_factor_v2(bucket_clip_edges[1], vCoSS[fidx1], vCoSS[fidx2]);
+ }
+ else {
+ fac1 = screen_px_line_point_factor_v2_persp(ps, bucket_clip_edges[0], vCo[fidx1], vCo[fidx2]);
+ fac2 = screen_px_line_point_factor_v2_persp(ps, bucket_clip_edges[1], vCo[fidx1], vCo[fidx2]);
+ }
interp_v2_v2v2(seam_subsection[0], lt_uv_pxoffset[fidx1], lt_uv_pxoffset[fidx2], fac1);
interp_v2_v2v2(seam_subsection[1], lt_uv_pxoffset[fidx1], lt_uv_pxoffset[fidx2], fac2);
@@ -2695,7 +2752,7 @@ static void project_paint_face_init(
interp_v3_v3v3(edge_verts_inset_clip[1], insetCos[fidx1], insetCos[fidx2], fac2);
- if (pixel_bounds_uv(seam_subsection, &bounds_px, ibuf->x, ibuf->y)) {
+ if (pixel_bounds_uv((const float (*)[2])seam_subsection, &bounds_px, ibuf->x, ibuf->y)) {
/* bounds between the seam rect and the uvspace bucket pixels */
has_isect = 0;
@@ -3104,6 +3161,7 @@ static void proj_paint_state_viewport_init(
mul_m4_m4m4(ps->projectMat, winmat, vmat);
}
+ invert_m4_m4(ps->projectMatInv, ps->projectMat);
/* viewDir - object relative */
copy_m3_m4(mat, viewinv);
@@ -3559,34 +3617,6 @@ static bool project_paint_winclip(
}
#endif //PROJ_DEBUG_WINCLIP
-/* Return true if face should be culled, false otherwise */
-static bool project_paint_backface_cull(
- const ProjPaintState *ps, const MLoopTri *lt,
- const ProjPaintFaceCoSS *coSS)
-{
- if (ps->do_backfacecull) {
- if (ps->do_mask_normal) {
- const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) };
- /* Since we are interpolating the normals of faces, we want to make
- * sure all the verts are pointing away from the view,
- * not just the face */
- if ((ps->vertFlags[lt_vtri[0]] & PROJ_VERT_CULL) &&
- (ps->vertFlags[lt_vtri[1]] & PROJ_VERT_CULL) &&
- (ps->vertFlags[lt_vtri[2]] & PROJ_VERT_CULL))
- {
- return true;
- }
- }
- else {
- if ((line_point_side_v2(coSS->v1, coSS->v2, coSS->v3) < 0.0f) != ps->is_flip_object) {
- return true;
- }
-
- }
- }
-
- return false;
-}
static void project_paint_build_proj_ima(
ProjPaintState *ps, MemArena *arena,
@@ -3631,6 +3661,7 @@ static void project_paint_prepare_all_faces(
TexPaintSlot *slot = NULL;
const MLoopTri *lt;
int image_index = -1, tri_index;
+ int prev_poly = -1;
for (tri_index = 0, lt = ps->dm_mlooptri; tri_index < ps->dm_totlooptri; tri_index++, lt++) {
bool is_face_sel;
@@ -3691,8 +3722,37 @@ static void project_paint_prepare_all_faces(
#endif //PROJ_DEBUG_WINCLIP
- if (project_paint_backface_cull(ps, lt, &coSS)) {
- continue;
+ /* backface culls individual triangles but mask normal will use polygon */
+ if (ps->do_backfacecull) {
+ if (ps->do_mask_normal) {
+ if (prev_poly != lt->poly) {
+ int iloop;
+ bool culled = true;
+ const MPoly *poly = ps->dm_mpoly + lt->poly;
+ int poly_loops = poly->totloop;
+ prev_poly = lt->poly;
+ for (iloop = 0; iloop < poly_loops; iloop++) {
+ if (!(ps->vertFlags[ps->dm_mloop[poly->loopstart + iloop].v] & PROJ_VERT_CULL)) {
+ culled = false;
+ break;
+ }
+ }
+
+ if (culled) {
+ /* poly loops - 2 is number of triangles for poly,
+ * but counter gets incremented when continuing, so decrease by 3 */
+ int poly_tri = poly_loops - 3;
+ tri_index += poly_tri;
+ lt += poly_tri;
+ continue;
+ }
+ }
+ }
+ else {
+ if ((line_point_side_v2(coSS.v1, coSS.v2, coSS.v3) < 0.0f) != ps->is_flip_object) {
+ continue;
+ }
+ }
}
}
@@ -4264,7 +4324,7 @@ static void do_projectpaint_soften(ProjPaintState *ps, ProjPixel *projPixel, flo
}
else {
premul_float_to_straight_uchar(rgba_ub, rgba);
- blend_color_interpolate_byte(rgba_ub, rgba_ub, projPixel->pixel.ch_pt, mask);
+ blend_color_interpolate_byte(rgba_ub, projPixel->pixel.ch_pt, rgba_ub, mask);
}
BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
}
@@ -4472,6 +4532,7 @@ static void *do_projectpaint_thread(void *ph_v)
break;
}
case BRUSH_GRADIENT_RADIAL:
+ default:
{
f = len_v2(p) / line_len;
break;
@@ -5338,7 +5399,10 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
if (w > maxsize) w = maxsize;
if (h > maxsize) h = maxsize;
- ibuf = ED_view3d_draw_offscreen_imbuf(scene, CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, false, R_ALPHAPREMUL, NULL, err_out);
+ ibuf = ED_view3d_draw_offscreen_imbuf(
+ scene, CTX_wm_view3d(C), CTX_wm_region(C),
+ w, h, IB_rect, false, R_ALPHAPREMUL, 0, NULL,
+ NULL, err_out);
if (!ibuf) {
/* Mostly happens when OpenGL offscreen buffer was failed to create, */
/* but could be other reasons. Should be handled in the future. nazgul */
@@ -5352,7 +5416,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
IMB_freeImBuf(ibuf);
if (image) {
- /* now for the trickyness. store the view projection here!
+ /* now for the trickiness. store the view projection here!
* re-projection will reuse this */
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 2254bc991b6..118f3a7571f 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -69,7 +69,7 @@
static EnumPropertyItem mode_items[] = {
{PAINT_MASK_FLOOD_VALUE, "VALUE", 0, "Value", "Set mask to the level specified by the 'value' property"},
- {PAINT_MASK_FLOOD_VALUE_INVERSE, "VALUE_INVERSE", 0, "Value Inverted", "Set mask to the level specified by the inverted 'value' property"},
+ {PAINT_MASK_FLOOD_VALUE_INVERSE, "VALUE_INVERSE", 0, "Value Inverted", "Set mask to the level specified by the inverted 'value' property"},
{PAINT_MASK_INVERT, "INVERT", 0, "Invert", "Invert the mask"},
{0}};
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index eebd49895ef..05eda4da63b 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -66,11 +66,12 @@ static int brush_add_exec(bContext *C, wmOperator *UNUSED(op))
Paint *paint = BKE_paint_get_active_from_context(C);
Brush *br = BKE_paint_brush(paint);
Main *bmain = CTX_data_main(C);
+ PaintMode mode = BKE_paintmode_get_active_from_context(C);
if (br)
br = BKE_brush_copy(br);
else
- br = BKE_brush_add(bmain, "Brush");
+ br = BKE_brush_add(bmain, "Brush", BKE_paint_object_mode_from_paint_mode(mode));
BKE_paint_brush_set(paint, br);
@@ -201,11 +202,11 @@ static int palette_color_add_exec(bContext *C, wmOperator *UNUSED(op))
color = BKE_palette_color_add(palette);
palette->active_color = BLI_listbase_count(&palette->colors) - 1;
- if (ELEM(mode, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D, PAINT_VERTEX)) {
+ if (ELEM(mode, ePaintTextureProjective, ePaintTexture2D, ePaintVertex)) {
copy_v3_v3(color->rgb, BKE_brush_color_get(scene, brush));
color->value = 0.0;
}
- else if (mode == PAINT_WEIGHT) {
+ else if (mode == ePaintWeight) {
zero_v3(color->rgb);
color->value = brush->weight;
}
@@ -431,9 +432,8 @@ static int brush_generic_tool_set(Main *bmain, Paint *paint, const int tool,
brush = brush_tool_cycle(bmain, brush_orig, tool, tool_offset, ob_mode);
if (!brush && brush_tool(brush_orig, tool_offset) != tool && create_missing) {
- brush = BKE_brush_add(bmain, tool_name);
+ brush = BKE_brush_add(bmain, tool_name, ob_mode);
brush_tool_set(brush, tool_offset, tool);
- brush->ob_mode = ob_mode;
brush->toggle_brush = brush_orig;
}
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index a6d80953178..b1ddf1172c8 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -194,7 +194,7 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata)
static bool paint_tool_require_location(Brush *brush, PaintMode mode)
{
switch (mode) {
- case PAINT_SCULPT:
+ case ePaintSculpt:
if (ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB))
{
@@ -224,6 +224,7 @@ static bool paint_brush_update(bContext *C,
bool location_sampled = false;
bool location_success = false;
bool do_random = false;
+ bool do_random_mask = false;
/* XXX: Use pressure value from first brush step for brushes which don't
* support strokes (grab, thumb). They depends on initial state and
* brush coord/pressure/etc.
@@ -271,9 +272,11 @@ static bool paint_brush_update(bContext *C,
}
if (paint_supports_dynamic_tex_coords(brush, mode)) {
- if (((brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) ||
- (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) ||
- (brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)))
+
+ if (ELEM(brush->mtex.brush_map_mode,
+ MTEX_MAP_MODE_VIEW,
+ MTEX_MAP_MODE_AREA,
+ MTEX_MAP_MODE_RANDOM))
{
do_random = true;
}
@@ -286,6 +289,15 @@ static bool paint_brush_update(bContext *C,
/* take care of mask texture, if any */
if (brush->mask_mtex.tex) {
+
+ if (ELEM(brush->mask_mtex.brush_map_mode,
+ MTEX_MAP_MODE_VIEW,
+ MTEX_MAP_MODE_AREA,
+ MTEX_MAP_MODE_RANDOM))
+ {
+ do_random_mask = true;
+ }
+
if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)
BKE_brush_randomize_texture_coords(ups, true);
else {
@@ -358,7 +370,9 @@ static bool paint_brush_update(bContext *C,
ups->brush_rotation += -brush->mtex.random_angle / 2.0f +
brush->mtex.random_angle * BLI_frand();
}
+ }
+ if (do_random_mask) {
if (brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RANDOM) {
ups->brush_rotation_sec += -brush->mask_mtex.random_angle / 2.0f +
brush->mask_mtex.random_angle * BLI_frand();
@@ -389,7 +403,7 @@ static bool paint_stroke_use_jitter(PaintMode mode, Brush *brush, bool invert)
/* jitter-ed brush gives weird and unpredictable result for this
* kinds of stroke, so manually disable jitter usage (sergey) */
use_jitter &= (brush->flag & (BRUSH_DRAG_DOT | BRUSH_ANCHORED)) == 0;
- use_jitter &= (!ELEM(mode, PAINT_TEXTURE_2D, PAINT_TEXTURE_PROJECTIVE) ||
+ use_jitter &= (!ELEM(mode, ePaintTexture2D, ePaintTextureProjective) ||
!(invert && brush->imagepaint_tool == PAINT_TOOL_CLONE));
@@ -760,13 +774,13 @@ bool paint_supports_dynamic_size(Brush *br, PaintMode mode)
return false;
switch (mode) {
- case PAINT_SCULPT:
+ case ePaintSculpt:
if (sculpt_is_grab_tool(br))
return false;
break;
- case PAINT_TEXTURE_2D: /* fall through */
- case PAINT_TEXTURE_PROJECTIVE:
+ case ePaintTexture2D: /* fall through */
+ case ePaintTextureProjective:
if ((br->imagepaint_tool == PAINT_TOOL_FILL) &&
(br->flag & BRUSH_USE_GRADIENT))
{
@@ -789,7 +803,7 @@ bool paint_supports_smooth_stroke(Brush *br, PaintMode mode)
}
switch (mode) {
- case PAINT_SCULPT:
+ case ePaintSculpt:
if (sculpt_is_grab_tool(br))
return false;
break;
@@ -802,7 +816,7 @@ bool paint_supports_smooth_stroke(Brush *br, PaintMode mode)
bool paint_supports_texture(PaintMode mode)
{
/* omit: PAINT_WEIGHT, PAINT_SCULPT_UV, PAINT_INVALID */
- return ELEM(mode, PAINT_SCULPT, PAINT_VERTEX, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D);
+ return ELEM(mode, ePaintSculpt, ePaintVertex, ePaintTextureProjective, ePaintTexture2D);
}
/* return true if the brush size can change during paint (normally used for pressure) */
@@ -812,7 +826,7 @@ bool paint_supports_dynamic_tex_coords(Brush *br, PaintMode mode)
return false;
switch (mode) {
- case PAINT_SCULPT:
+ case ePaintSculpt:
if (sculpt_is_grab_tool(br))
return false;
break;
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index c76bae01308..7b66632fa42 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -46,7 +46,7 @@
#include "BLI_listbase.h"
#include "BLI_rect.h"
-#include "BLF_translation.h"
+#include "BLT_translation.h"
#include "BKE_brush.h"
#include "BKE_context.h"
@@ -572,7 +572,7 @@ void BRUSH_OT_curve_preset(wmOperatorType *ot)
ot->poll = brush_curve_preset_poll;
prop = RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", "");
- RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 23f388d2a58..8daad9deea9 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -1956,7 +1956,7 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
paint_cursor_start(C, weight_paint_poll);
- BKE_paint_init(&scene->toolsettings->unified_paint_settings, &wp->paint, PAINT_CURSOR_WEIGHT_PAINT);
+ BKE_paint_init(scene, ePaintWeight, PAINT_CURSOR_WEIGHT_PAINT);
/* weight paint specific */
ED_mesh_mirror_spatial_table(ob, NULL, NULL, 's');
@@ -2564,7 +2564,7 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
paint_cursor_start(C, vertex_paint_poll);
- BKE_paint_init(&scene->toolsettings->unified_paint_settings, &vp->paint, PAINT_CURSOR_VERTEX_PAINT);
+ BKE_paint_init(scene, ePaintVertex, PAINT_CURSOR_VERTEX_PAINT);
}
/* update modifier stack for mapping requirements */
@@ -2675,7 +2675,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
brush->mtex.tex;
/* are we painting onto a modified mesh?,
- * if not we can skip face map trickyness */
+ * if not we can skip face map trickiness */
if (vertex_paint_use_fast_update_check(ob)) {
vpd->use_fast_update = true;
/* printf("Fast update!\n");*/
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index dd10836ef9a..07511e1924e 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -41,7 +41,7 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
-#include "BLF_translation.h"
+#include "BLT_translation.h"
#include "DNA_customdata_types.h"
#include "DNA_mesh_types.h"
@@ -246,6 +246,9 @@ typedef struct StrokeCache {
* calc_brush_local_mat() and used in tex_strength(). */
float brush_local_mat[4][4];
+ float plane_offset[3]; /* used to shift the plane around when doing tiled strokes */
+ int tile_pass;
+
float last_center[3];
int radial_symmetry_pass;
float symm_rot_mat[4][4];
@@ -2501,8 +2504,8 @@ static void calc_sculpt_plane(
if (ss->cache->mirror_symmetry_pass == 0 &&
ss->cache->radial_symmetry_pass == 0 &&
- (ss->cache->first_time || !(brush->flag & BRUSH_ORIGINAL_NORMAL) ||
- (sd->paint.symmetry_flags & PAINT_TILE_AXIS_ALL)))
+ ss->cache->tile_pass == 0 &&
+ (ss->cache->first_time || !(brush->flag & BRUSH_ORIGINAL_NORMAL)))
{
switch (brush->sculpt_plane) {
case SCULPT_DISP_DIR_VIEW:
@@ -2558,6 +2561,9 @@ static void calc_sculpt_plane(
/* for flatten center */
mul_m4_v3(ss->cache->symm_rot_mat, r_area_co);
+
+ /* shift the plane for the current tile */
+ add_v3_v3(r_area_co, ss->cache->plane_offset);
}
}
@@ -3438,6 +3444,7 @@ static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm,
unit_m4(cache->symm_rot_mat);
unit_m4(cache->symm_rot_mat_inv);
+ zero_v3(cache->plane_offset);
if (axis) { /* expects XYZ */
rotate_m4(cache->symm_rot_mat, axis, angle);
@@ -3462,37 +3469,48 @@ static void do_tiled(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings
const float radius = cache->radius;
const float *bbMin = ob->bb->vec[0];
const float *bbMax = ob->bb->vec[6];
-
- float start[3];
- float end[3];
const float *step = sd->paint.tile_offset;
int dim;
+ /* These are integer locations, for real location: multiply with step and add orgLoc. So 0,0,0 is at orgLoc. */
+ int start[3];
+ int end[3];
+ int cur[3];
+
+ float orgLoc[3]; /* position of the "prototype" stroke for tiling */
+ copy_v3_v3(orgLoc, cache->location);
+
for (dim = 0; dim < 3; ++dim) {
if ((sd->paint.symmetry_flags & (PAINT_TILE_X << dim)) && step[dim] > 0) {
- int n = (cache->location[dim] - bbMin[dim] + radius) / step[dim];
- start[dim] = cache->location[dim] - n * step[dim];
- end[dim] = bbMax[dim] + radius;
+ start[dim] = (bbMin[dim] - orgLoc[dim] - radius) / step[dim];
+ end[dim] = (bbMax[dim] - orgLoc[dim] + radius) / step[dim];
}
else
- start[dim] = end[dim] = cache->location[dim];
+ start[dim] = end[dim] = 0;
}
- copy_v3_v3(cache->location, start);
- do {
- do {
- do {
- action(sd, ob, brush, ups);
- cache->location[2] += step[2];
- } while (cache->location[2] < end[2]);
- cache->location[2] = start[2];
+ /* first do the "untiled" position to initialize the stroke for this location */
+ cache->tile_pass = 0;
+ action(sd, ob, brush, ups);
+
+ /* now do it for all the tiles */
+ copy_v3_v3_int(cur, start);
+ for (cur[0] = start[0]; cur[0] <= end[0]; ++cur[0]) {
+ for (cur[1] = start[1]; cur[1] <= end[1]; ++cur[1]) {
+ for (cur[2] = start[2]; cur[2] <= end[2]; ++cur[2]) {
+ if (!cur[0] && !cur[1] && !cur[2])
+ continue; /* skip tile at orgLoc, this was already handled before all others */
- cache->location[1] += step[1];
- } while (cache->location[1] < end[1]);
- cache->location[1] = start[1];
+ ++cache->tile_pass;
- cache->location[0] += step[0];
- } while (cache->location[0] < end[0]);
+ for (dim = 0; dim < 3; ++dim) {
+ cache->location[dim] = cur[dim] * step[dim] + orgLoc[dim];
+ cache->plane_offset[dim] = cur[dim] * step[dim];
+ }
+ action(sd, ob, brush, ups);
+ }
+ }
+ }
}
@@ -4044,7 +4062,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
* brush coord/pressure/etc.
* It's more an events design issue, which doesn't split coordinate/pressure/angle
* changing events. We should avoid this after events system re-design */
- if (paint_supports_dynamic_size(brush, PAINT_SCULPT) || cache->first_time) {
+ if (paint_supports_dynamic_size(brush, ePaintSculpt) || cache->first_time) {
cache->pressure = RNA_float_get(ptr, "pressure");
}
@@ -4061,7 +4079,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
}
}
- if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush, PAINT_SCULPT)) {
+ if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush, ePaintSculpt)) {
cache->radius = cache->initial_radius * cache->pressure;
}
else {
@@ -4199,7 +4217,10 @@ static float sculpt_raycast_init(ViewContext *vc, const float mouse[2], float ra
sub_v3_v3v3(ray_normal, ray_end, ray_start);
dist = normalize_v3(ray_normal);
- if (!rv3d->is_persp) {
+ if ((rv3d->is_persp == false) &&
+ /* if the ray is clipped, don't adjust its start/end */
+ ((rv3d->rflag & RV3D_CLIPPING) == 0))
+ {
BKE_pbvh_raycast_project_ray_root(ob->sculpt->pbvh, original, ray_start, ray_end, ray_normal);
/* recalculate the normal */
@@ -4879,7 +4900,7 @@ static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op, co
if (!ELEM(i, CD_MVERT, CD_MEDGE, CD_MFACE, CD_MLOOP, CD_MPOLY, CD_PAINT_MASK, CD_ORIGINDEX) &&
(CustomData_has_layer(&me->vdata, i) ||
CustomData_has_layer(&me->edata, i) ||
- CustomData_has_layer(&me->fdata, i)))
+ CustomData_has_layer(&me->ldata, i)))
{
vdata = true;
break;
@@ -5123,7 +5144,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
"Object has negative scale, sculpting may be unpredictable");
}
- BKE_paint_init(&ts->unified_paint_settings, &ts->sculpt->paint, PAINT_CURSOR_SCULPT);
+ BKE_paint_init(scene, ePaintSculpt, PAINT_CURSOR_SCULPT);
paint_cursor_start(C, sculpt_poll_view3d);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index e01d8a6bd17..405ac3f6808 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -224,8 +224,9 @@ static void brush_drawcursor_uvsculpt(bContext *C, int x, int y, void *UNUSED(cu
}
-void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings)
+void ED_space_image_uv_sculpt_update(wmWindowManager *wm, Scene *scene)
{
+ ToolSettings *settings = scene->toolsettings;
if (settings->use_uv_sculpt) {
if (!settings->uvsculpt) {
settings->uvsculpt = MEM_callocN(sizeof(*settings->uvsculpt), "UV Smooth paint");
@@ -236,7 +237,7 @@ void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings
settings->uvsculpt->paint.flags |= PAINT_SHOW_BRUSH;
}
- BKE_paint_init(&settings->unified_paint_settings, &settings->uvsculpt->paint, PAINT_CURSOR_SCULPT);
+ BKE_paint_init(scene, ePaintSculptUV, PAINT_CURSOR_SCULPT);
settings->uvsculpt->paint.paint_cursor = WM_paint_cursor_activate(wm, uv_sculpt_brush_poll,
brush_drawcursor_uvsculpt, NULL);