Bugfix #22040
[blender.git] / source / blender / editors / sculpt_paint / paint_image.c
index cd498c274cf3eea382f0da5134ef45705c2d66ca..46bcd1f1c0da2cd147b98137fc3f47600fe98b7b 100644 (file)
@@ -163,17 +163,17 @@ typedef struct ImagePaintRegion {
 #define PROJ_DEBUG_WINCLIP 1
 
 /* projectFaceSeamFlags options */
-//#define PROJ_FACE_IGNORE     1<<0    /* When the face is hidden, backfacing or occluded */
-//#define PROJ_FACE_INIT       1<<1    /* When we have initialized the faces data */
-#define PROJ_FACE_SEAM1        1<<0    /* If this face has a seam on any of its edges */
-#define PROJ_FACE_SEAM2        1<<1
-#define PROJ_FACE_SEAM3        1<<2
-#define PROJ_FACE_SEAM4        1<<3
-
-#define PROJ_FACE_NOSEAM1      1<<4
-#define PROJ_FACE_NOSEAM2      1<<5
-#define PROJ_FACE_NOSEAM3      1<<6
-#define PROJ_FACE_NOSEAM4      1<<7
+//#define PROJ_FACE_IGNORE     (1<<0)  /* When the face is hidden, backfacing or occluded */
+//#define PROJ_FACE_INIT       (1<<1)  /* When we have initialized the faces data */
+#define PROJ_FACE_SEAM1        (1<<0)  /* If this face has a seam on any of its edges */
+#define PROJ_FACE_SEAM2        (1<<1)
+#define PROJ_FACE_SEAM3        (1<<2)
+#define PROJ_FACE_SEAM4        (1<<3)
+
+#define PROJ_FACE_NOSEAM1      (1<<4)
+#define PROJ_FACE_NOSEAM2      (1<<5)
+#define PROJ_FACE_NOSEAM3      (1<<6)
+#define PROJ_FACE_NOSEAM4      (1<<7)
 
 #define PROJ_SRC_VIEW          1
 #define PROJ_SRC_IMAGE_CAM     2
@@ -189,8 +189,8 @@ typedef struct ImagePaintRegion {
 #define PROJ_FACE_SCALE_SEAM   0.99f
 
 #define PROJ_BUCKET_NULL               0
-#define PROJ_BUCKET_INIT               1<<0
-// #define PROJ_BUCKET_CLONE_INIT      1<<1
+#define PROJ_BUCKET_INIT               (1<<0)
+// #define PROJ_BUCKET_CLONE_INIT      (1<<1)
 
 /* used for testing doubles, if a point is on a line etc */
 #define PROJ_GEOM_TOLERANCE 0.00075f
@@ -383,7 +383,7 @@ static void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int
                        return tile->rect;
        
        if (*tmpibuf==NULL)
-               *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat|IB_rect, 0);
+               *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat|IB_rect);
        
        tile= MEM_callocN(sizeof(UndoImageTile), "UndoImageTile");
        strcpy(tile->idname, ima->id.name);
@@ -410,7 +410,7 @@ static void image_undo_restore(bContext *C, ListBase *lb)
        UndoImageTile *tile;
 
        tmpibuf= IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32,
-                                                       IB_rectfloat|IB_rect, 0);
+                                                       IB_rectfloat|IB_rect);
        
        for(tile=lb->first; tile; tile=tile->next) {
                /* find image based on name, pointer becomes invalid with global undo */
@@ -1011,8 +1011,11 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl
        float puv[4][2]; /* pixelspace uv's */
        float no1[2], no2[2], no3[2], no4[2]; /* normals */
        float dir1[2], dir2[2], dir3[2], dir4[2];
-       float ibuf_inv[2] = {1.0f / (float)ibuf_x, 1.0f / (float)ibuf_y};
-       
+       float ibuf_inv[2];
+
+       ibuf_inv[0]= 1.0f / (float)ibuf_x;
+       ibuf_inv[1]= 1.0f / (float)ibuf_y;
+
        /* make UV's in pixel space so we can */
        puv[0][0] = orig_uv[0][0] * ibuf_x;
        puv[0][1] = orig_uv[0][1] * ibuf_y;
@@ -3961,7 +3964,7 @@ static int project_paint_stroke(ProjPaintState *ps, BrushPainter *painter, int *
 
 /* Imagepaint Partial Redraw & Dirty Region */
 
-static void imapaint_clear_partial_redraw()
+static void imapaint_clear_partial_redraw(void)
 {
        memset(&imapaintpartial, 0, sizeof(imapaintpartial));
 }
@@ -4010,8 +4013,9 @@ static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, s
        if(ibuf->rect_float)
                /* TODO - should just update a portion from imapaintpartial! */
                imb_freerectImBuf(ibuf); /* force recreate of char rect */
+       
        if(ibuf->mipmap[0])
-               imb_freemipmapImBuf(ibuf);
+               ibuf->userflags |= IB_MIPMAP_INVALID;
 
        /* todo: should set_tpage create ->rect? */
        if(texpaint || (sima && sima->lock)) {
@@ -4178,7 +4182,7 @@ static void imapaint_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos)
        int a, tot;
 
        imapaint_set_region(region, 0, 0, pos[0], pos[1], ibufb->x, ibufb->y);
-       tot= imapaint_torus_split_region(region, ibuf, ibufb);
+       tot= imapaint_torus_split_region(region, ibufb, ibuf);
 
        for(a=0; a<tot; a++)
                IMB_rectblend(ibufb, ibuf, region[a].destx, region[a].desty,
@@ -4191,7 +4195,7 @@ static ImBuf *imapaint_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
        /* note: allocImbuf returns zero'd memory, so regions outside image will
           have zero alpha, and hence not be blended onto the image */
        int w=ibufb->x, h=ibufb->y, destx=0, desty=0, srcx=pos[0], srcy=pos[1];
-       ImBuf *clonebuf= IMB_allocImBuf(w, h, ibufb->depth, ibufb->flags, 0);
+       ImBuf *clonebuf= IMB_allocImBuf(w, h, ibufb->depth, ibufb->flags);
 
        IMB_rectclip(clonebuf, ibuf, &destx, &desty, &srcx, &srcy, &w, &h);
        IMB_rectblend(clonebuf, ibuf, destx, desty, srcx, srcy, w, h,
@@ -4523,6 +4527,8 @@ typedef struct PaintOperation {
 
        ViewContext vc;
        wmTimer *timer;
+
+       short restore_projection;
 } PaintOperation;
 
 static void paint_redraw(bContext *C, ImagePaintState *s, int final)
@@ -4608,6 +4614,13 @@ static int texture_paint_init(bContext *C, wmOperator *op)
        pop->first= 1;
        op->customdata= pop;
        
+       /* XXX: Soften tool does not support projection painting atm, so just disable
+               projection for this brush */
+       if(brush->imagepaint_tool == PAINT_TOOL_SOFTEN) {
+               settings->imapaint.flag |= IMAGEPAINT_PROJECT_DISABLE;
+               pop->restore_projection = 1;
+       }
+
        /* initialize from context */
        if(CTX_wm_region_view3d(C)) {
                pop->mode= PAINT_MODE_3D;
@@ -4728,6 +4741,9 @@ static void paint_exit(bContext *C, wmOperator *op)
        if(pop->timer)
                WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), pop->timer);
 
+       if(pop->restore_projection)
+               settings->imapaint.flag &= ~IMAGEPAINT_PROJECT_DISABLE;
+
        settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
        imapaint_canvas_free(&pop->s);
        brush_painter_free(pop->painter);
@@ -4961,23 +4977,38 @@ static void toggle_paint_cursor(bContext *C, int enable)
                settings->imapaint.paintcursor= WM_paint_cursor_activate(CTX_wm_manager(C), image_paint_poll, brush_drawcursor, NULL);
 }
 
+/* enable the paint cursor if it isn't already.
+
+   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)
+{
+       ImagePaintSettings *imapaint = &settings->imapaint;
+
+       if(!imapaint->paintcursor) {
+               imapaint->paintcursor =
+                       WM_paint_cursor_activate(wm, image_paint_poll,
+                                                brush_drawcursor, NULL);
+       }
+}
+
 /* ************ image paint radial control *************/
 static int paint_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
        float zoom;
        ToolSettings *ts = CTX_data_scene(C)->toolsettings;
        get_imapaint_zoom(C, &zoom, &zoom);
-       toggle_paint_cursor(C, !ts->imapaint.paintcursor);
+       toggle_paint_cursor(C, 0);
        brush_radial_control_invoke(op, paint_brush(&ts->imapaint.paint), zoom);
        return WM_radial_control_invoke(C, op, event);
 }
 
 static int paint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
 {
-       ToolSettings *ts = CTX_data_scene(C)->toolsettings;
        int ret = WM_radial_control_modal(C, op, event);
        if(ret != OPERATOR_RUNNING_MODAL)
-                       toggle_paint_cursor(C, !ts->imapaint.paintcursor);
+               toggle_paint_cursor(C, 1);
        return ret;
 }
 
@@ -5299,7 +5330,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
                toggle_paint_cursor(C, 1);
        }
 
-       DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_SCENE|ND_MODE, scene);
 
        return OPERATOR_FINISHED;
@@ -5382,13 +5413,11 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
 {
        Image *image= BLI_findlink(&CTX_data_main(C)->image, RNA_enum_get(op->ptr, "image"));
        Scene *scene= CTX_data_scene(C);
-       ProjPaintState ps;
+       ProjPaintState ps= {0};
        int orig_brush_size;
        IDProperty *idgroup;
        IDProperty *view_data= NULL;
 
-       memset(&ps, 0, sizeof(ps));
-
        project_state_init(C, OBACT, &ps);
 
        if(ps.ob==NULL || ps.ob->type != OB_MESH) {
@@ -5569,6 +5598,7 @@ void PAINT_OT_image_from_view(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec= texture_paint_image_from_view_exec;
+       ot->poll= ED_operator_region_view3d_active;
 
        /* flags */
        ot->flag= OPTYPE_REGISTER;