~ubuntu-branches/ubuntu/lucid/blender/lucid

« back to all changes in this revision

Viewing changes to source/blender/src/imagepaint.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2009-08-06 22:32:19 UTC
  • mfrom: (1.2.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090806223219-8z4eej1u8levu4pz
Tags: 2.49a+dfsg-0ubuntu1
* Merge from debian unstable, remaining changes:
  - debian/control: Build-depend on python-2.6 rather than python-2.5.
  - debian/misc/*.desktop: Add Spanish translation to .desktop 
    files.
  - debian/pyversions: 2.6.
  - debian/rules: Clean *.o of source/blender/python/api2_2x/
* New upstream release (LP: #382153).
* Refreshed patches:
  - 01_sanitize_sys.patch
  - 02_tmp_in_HOME
  - 10_use_systemwide_ftgl
  - 70_portability_platform_detection
* Removed patches merged upstream:
  - 30_fix_python_syntax_warning
  - 90_ubuntu_ffmpeg_52_changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
 
 * $Id: imagepaint.c 17094 2008-10-17 13:34:20Z blendix $
 
2
 * $Id: imagepaint.c 20469 2009-05-28 06:13:56Z campbellbarton $
3
3
 * imagepaint.c
4
4
 *
5
5
 * Functions to paint images in 2D and 3D.
23
23
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24
24
 * All rights reserved.
25
25
 *
26
 
 * The Original Code is: all of this file.
 
26
 * The Original Code is: some of this file.
27
27
 *
28
 
 * Contributor(s): Jens Ole Wund (bjornmose)
 
28
 * Contributor(s): Jens Ole Wund (bjornmose), Campbell Barton (ideasman42)
29
29
 *
30
30
 * ***** END GPL LICENSE BLOCK *****
31
31
 */
46
46
#include "BLI_arithb.h"
47
47
#include "BLI_blenlib.h"
48
48
#include "BLI_dynstr.h"
 
49
#include "BLI_linklist.h"
 
50
#include "BLI_memarena.h"
49
51
#include "PIL_time.h"
 
52
#include "BLI_threads.h"
50
53
 
51
54
#include "IMB_imbuf.h"
52
55
#include "IMB_imbuf_types.h"
70
73
#include "BKE_mesh.h"
71
74
#include "BKE_node.h"
72
75
#include "BKE_utildefines.h"
 
76
#include "BKE_DerivedMesh.h"
73
77
 
74
78
#include "BIF_interface.h"
75
79
#include "BIF_mywindow.h"
77
81
#include "BIF_space.h"
78
82
#include "BIF_toolbox.h"
79
83
 
 
84
#include "BIF_editview.h" /* only for mouse_cursor - could remove this later */
 
85
 
80
86
#include "BSE_drawipo.h"
81
87
#include "BSE_node.h"
82
88
#include "BSE_trans_types.h"
83
89
#include "BSE_view.h"
 
90
#include "BSE_drawview.h" /* view3d_test_clipping */
84
91
 
85
92
#include "BDR_imagepaint.h"
86
93
#include "BDR_vpaint.h"
87
 
 
88
94
#include "GPU_draw.h"
89
95
 
90
96
#include "GHOST_Types.h"
95
101
 
96
102
/* Defines and Structs */
97
103
 
98
 
#define IMAPAINT_CHAR_TO_FLOAT(c) (c/255.0f)
99
 
 
100
 
#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { c[0]=FTOCHAR(f[0]); \
101
 
        c[1]=FTOCHAR(f[1]); c[2]=FTOCHAR(f[2]); }
102
 
#define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { f[0]=IMAPAINT_CHAR_TO_FLOAT(c[0]); \
103
 
        f[1]=IMAPAINT_CHAR_TO_FLOAT(c[1]); f[2]=IMAPAINT_CHAR_TO_FLOAT(c[2]); }
 
104
#define IMAPAINT_CHAR_TO_FLOAT(c) ((c)/255.0f)
 
105
 
 
106
#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { (c)[0]=FTOCHAR((f)[0]); (c)[1]=FTOCHAR((f)[1]); (c)[2]=FTOCHAR((f)[2]); }
 
107
#define IMAPAINT_FLOAT_RGBA_TO_CHAR(c, f) { (c)[0]=FTOCHAR((f)[0]); (c)[1]=FTOCHAR((f)[1]); (c)[2]=FTOCHAR((f)[2]); (c)[3]=FTOCHAR((f)[3]); }
 
108
 
 
109
#define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { (f)[0]=IMAPAINT_CHAR_TO_FLOAT((c)[0]); (f)[1]=IMAPAINT_CHAR_TO_FLOAT((c)[1]); (f)[2]=IMAPAINT_CHAR_TO_FLOAT((c)[2]); }
 
110
#define IMAPAINT_CHAR_RGBA_TO_FLOAT(f, c) { (f)[0]=IMAPAINT_CHAR_TO_FLOAT((c)[0]); (f)[1]=IMAPAINT_CHAR_TO_FLOAT((c)[1]); (f)[2]=IMAPAINT_CHAR_TO_FLOAT((c)[2]); (f)[3]=IMAPAINT_CHAR_TO_FLOAT((c)[3]); }
104
111
#define IMAPAINT_FLOAT_RGB_COPY(a, b) VECCOPY(a, b)
105
112
 
106
113
#define IMAPAINT_TILE_BITS                      6
109
116
 
110
117
#define MAXUNDONAME     64
111
118
 
 
119
static void imapaint_image_update(Image *image, ImBuf *ibuf, short texpaint);
 
120
 
 
121
 
112
122
typedef struct ImagePaintState {
113
123
        Brush *brush;
114
124
        short tool, blend;
126
136
        float uv[2];
127
137
} ImagePaintState;
128
138
 
 
139
typedef struct ImagePaintPartialRedraw {
 
140
        int x1, y1, x2, y2;
 
141
        int enabled;
 
142
} ImagePaintPartialRedraw;
 
143
 
 
144
 
 
145
/* ProjectionPaint defines */
 
146
 
 
147
/* approx the number of buckets to have under the brush,
 
148
 * used with the brush size to set the ps->buckets_x and ps->buckets_y value.
 
149
 * 
 
150
 * When 3 - a brush should have ~9 buckets under it at once
 
151
 * ...this helps for threading while painting as well as
 
152
 * avoiding initializing pixels that wont touch the brush */
 
153
#define PROJ_BUCKET_BRUSH_DIV 4
 
154
 
 
155
#define PROJ_BUCKET_RECT_MIN 4
 
156
#define PROJ_BUCKET_RECT_MAX 256
 
157
 
 
158
#define PROJ_BOUNDBOX_DIV 8
 
159
#define PROJ_BOUNDBOX_SQUARED  (PROJ_BOUNDBOX_DIV * PROJ_BOUNDBOX_DIV)
 
160
 
 
161
//#define PROJ_DEBUG_PAINT 1
 
162
//#define PROJ_DEBUG_NOSEAMBLEED 1
 
163
//#define PROJ_DEBUG_PRINT_CLIP 1
 
164
#define PROJ_DEBUG_WINCLIP 1
 
165
 
 
166
/* projectFaceSeamFlags options */
 
167
//#define PROJ_FACE_IGNORE      1<<0    /* When the face is hidden, backfacing or occluded */
 
168
//#define PROJ_FACE_INIT        1<<1    /* When we have initialized the faces data */
 
169
#define PROJ_FACE_SEAM1 1<<0    /* If this face has a seam on any of its edges */
 
170
#define PROJ_FACE_SEAM2 1<<1
 
171
#define PROJ_FACE_SEAM3 1<<2
 
172
#define PROJ_FACE_SEAM4 1<<3
 
173
 
 
174
#define PROJ_FACE_NOSEAM1       1<<4
 
175
#define PROJ_FACE_NOSEAM2       1<<5
 
176
#define PROJ_FACE_NOSEAM3       1<<6
 
177
#define PROJ_FACE_NOSEAM4       1<<7
 
178
 
 
179
/* a slightly scaled down face is used to get fake 3D location for edge pixels in the seams
 
180
 * as this number approaches  1.0f the likelihood increases of float precision errors where
 
181
 * it is occluded by an adjacent face */
 
182
#define PROJ_FACE_SCALE_SEAM    0.99f
 
183
 
 
184
#define PROJ_BUCKET_NULL                0
 
185
#define PROJ_BUCKET_INIT                1<<0
 
186
// #define PROJ_BUCKET_CLONE_INIT       1<<1
 
187
 
 
188
/* used for testing doubles, if a point is on a line etc */
 
189
#define PROJ_GEOM_TOLERANCE 0.00075f
 
190
 
 
191
/* vert flags */
 
192
#define PROJ_VERT_CULL 1
 
193
 
 
194
#define PI_80_DEG ((M_PI_2 / 9) * 8)
 
195
 
 
196
/* This is mainly a convenience struct used so we can keep an array of images we use
 
197
 * Thir imbufs, etc, in 1 array, When using threads this array is copied for each thread
 
198
 * because 'partRedrawRect' and 'touch' values would not be thread safe */
 
199
typedef struct ProjPaintImage {
 
200
        Image *ima;
 
201
        ImBuf *ibuf;
 
202
        ImagePaintPartialRedraw *partRedrawRect;
 
203
        struct UndoTile **undoRect; /* only used to build undo tiles after painting */
 
204
        int touch;
 
205
} ProjPaintImage;
 
206
 
 
207
/* Main projection painting struct passed to all projection painting functions */
 
208
typedef struct ProjPaintState {
 
209
        Brush *brush;
 
210
        short tool, blend;
 
211
        Object *ob;
 
212
        /* end similarities with ImagePaintState */
 
213
        
 
214
        DerivedMesh    *dm;
 
215
        int                     dm_totface;
 
216
        int                     dm_totvert;
 
217
        
 
218
        MVert              *dm_mvert;
 
219
        MFace              *dm_mface;
 
220
        MTFace             *dm_mtface;
 
221
        MTFace             *dm_mtface_clone;    /* other UV layer, use for cloning between layers */
 
222
        MTFace             *dm_mtface_mask;
 
223
        
 
224
        /* projection painting only */
 
225
        MemArena *arena_mt[BLENDER_MAX_THREADS];/* for multithreading, the first item is sometimes used for non threaded cases too */
 
226
        LinkNode **bucketRect;                          /* screen sized 2D array, each pixel has a linked list of ProjPixel's */
 
227
        LinkNode **bucketFaces;                         /* bucketRect aligned array linkList of faces overlapping each bucket */
 
228
        unsigned char *bucketFlags;                                     /* store if the bucks have been initialized  */
 
229
#ifndef PROJ_DEBUG_NOSEAMBLEED
 
230
        char *faceSeamFlags;                            /* store info about faces, if they are initialized etc*/
 
231
        float (*faceSeamUVs)[4][2];                     /* expanded UVs for faces to use as seams */
 
232
        LinkNode **vertFaces;                           /* Only needed for when seam_bleed_px is enabled, use to find UV seams */
 
233
#endif
 
234
        char *vertFlags;                                        /* store options per vert, now only store if the vert is pointing away from the view */
 
235
        int buckets_x;                                          /* The size of the bucket grid, the grid span's screenMin/screenMax so you can paint outsize the screen or with 2 brushes at once */
 
236
        int buckets_y;
 
237
        
 
238
        ProjPaintImage *projImages;
 
239
        
 
240
        int image_tot;                          /* size of projectImages array */
 
241
        
 
242
        float (*screenCoords)[4];       /* verts projected into floating point screen space */
 
243
        
 
244
        float screenMin[2];                     /* 2D bounds for mesh verts on the screen's plane (screenspace) */
 
245
        float screenMax[2]; 
 
246
        float screen_width;                     /* Calculated from screenMin & screenMax */
 
247
        float screen_height;
 
248
        
 
249
        /* options for projection painting */
 
250
        int do_layer_clone;
 
251
        int do_layer_mask;
 
252
        int do_layer_mask_inv;
 
253
        
 
254
        short do_occlude;                       /* Use raytraced occlusion? - ortherwise will paint right through to the back*/
 
255
        short do_backfacecull;  /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
 
256
        short do_mask_normal;                   /* mask out pixels based on their normals */
 
257
        float normal_angle;                             /* what angle to mask at*/
 
258
        float normal_angle_inner;
 
259
        float normal_angle_range;               /* difference between normal_angle and normal_angle_inner, for easy access */
 
260
        
 
261
        short is_ortho;
 
262
        short is_airbrush;                                      /* only to avoid using (ps.brush->flag & BRUSH_AIRBRUSH) */
 
263
        short is_texbrush;                                      /* only to avoid running  */
 
264
#ifndef PROJ_DEBUG_NOSEAMBLEED
 
265
        float seam_bleed_px;
 
266
#endif
 
267
        /* clone vars */
 
268
        float cloneOffset[2];
 
269
        
 
270
        float projectMat[4][4];         /* Projection matrix, use for getting screen coords */
 
271
        float viewMat[4][4];
 
272
        float viewDir[3];                       /* View vector, use for do_backfacecull and for ray casting with an ortho viewport  */
 
273
        float viewPos[3];                       /* View location in object relative 3D space, so can compare to verts  */
 
274
        float clipsta, clipend;
 
275
        
 
276
        /* threads */
 
277
        int thread_tot;
 
278
        int bucketMin[2];
 
279
        int bucketMax[2];
 
280
        int context_bucket_x, context_bucket_y; /* must lock threads while accessing these */
 
281
} ProjPaintState;
 
282
 
 
283
typedef union pixelPointer
 
284
{
 
285
        float *f_pt;                    /* float buffer */
 
286
        unsigned int *uint_pt; /* 2 ways to access a char buffer */
 
287
        unsigned char *ch_pt;
 
288
} PixelPointer;
 
289
 
 
290
typedef union pixelStore
 
291
{
 
292
        unsigned char ch[4];
 
293
        unsigned int uint;
 
294
        float f[4];
 
295
} PixelStore;
 
296
 
 
297
typedef struct ProjPixel {
 
298
        float projCoSS[2]; /* the floating point screen projection of this pixel */
 
299
        
 
300
        /* Only used when the airbrush is disabled.
 
301
         * Store the max mask value to avoid painting over an area with a lower opacity
 
302
         * with an advantage that we can avoid touching the pixel at all, if the 
 
303
         * new mask value is lower then mask_max */
 
304
        unsigned short mask_max;
 
305
        
 
306
        /* for various reasons we may want to mask out painting onto this pixel */
 
307
        unsigned short mask;
 
308
        
 
309
        short x_px, y_px;
 
310
        
 
311
        PixelStore origColor;
 
312
        PixelStore newColor;
 
313
        PixelPointer pixel;
 
314
        
 
315
        short image_index; /* if anyone wants to paint onto more then 32768 images they can bite me */
 
316
        unsigned char bb_cell_index;
 
317
} ProjPixel;
 
318
 
 
319
typedef struct ProjPixelClone {
 
320
        struct ProjPixel __pp;
 
321
        PixelStore clonepx;
 
322
} ProjPixelClone;
 
323
 
 
324
/* Finish projection painting structs */
 
325
 
 
326
 
129
327
typedef struct UndoTile {
130
328
        struct UndoTile *next, *prev;
131
329
        ID id;
136
334
typedef struct UndoElem {
137
335
        struct UndoElem *next, *prev;
138
336
        char name[MAXUNDONAME];
139
 
        unsigned long undosize;
 
337
        uintptr_t undosize;
140
338
 
141
339
        ImBuf *ibuf;
142
340
        ListBase tiles;
143
341
} UndoElem;
144
342
 
145
 
typedef struct ImagePaintPartialRedraw {
146
 
        int x1, y1, x2, y2;
147
 
        int enabled;
148
 
} ImagePaintPartialRedraw;
149
 
 
150
343
static ListBase undobase = {NULL, NULL};
151
344
static UndoElem *curundo = NULL;
152
345
static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0};
161
354
        IMB_rectcpy(tmpibuf, ibuf, 0, 0, tile->x*IMAPAINT_TILE_SIZE,
162
355
                tile->y*IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
163
356
 
164
 
        if(ibuf->rect_float) SWAP(void*, tmpibuf->rect_float, tile->rect)
165
 
        else SWAP(void*, tmpibuf->rect, tile->rect)
 
357
        if(ibuf->rect_float) {
 
358
                SWAP(void*, tmpibuf->rect_float, tile->rect);
 
359
        } else {
 
360
                SWAP(void*, tmpibuf->rect, tile->rect);
 
361
        }
166
362
        
167
363
        if(restore)
168
364
                IMB_rectcpy(ibuf, tmpibuf, tile->x*IMAPAINT_TILE_SIZE,
169
365
                        tile->y*IMAPAINT_TILE_SIZE, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
170
366
}
171
367
 
 
368
static UndoTile *undo_init_tile(ID *id, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile)
 
369
{
 
370
        UndoTile *tile;
 
371
        int allocsize;
 
372
        
 
373
        if (*tmpibuf==NULL)
 
374
                *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat|IB_rect, 0);
 
375
        
 
376
        tile= MEM_callocN(sizeof(UndoTile), "ImaUndoTile");
 
377
        tile->id= *id;
 
378
        tile->x= x_tile;
 
379
        tile->y= y_tile;
 
380
 
 
381
        allocsize= IMAPAINT_TILE_SIZE*IMAPAINT_TILE_SIZE*4;
 
382
        allocsize *= (ibuf->rect_float)? sizeof(float): sizeof(char);
 
383
        tile->rect= MEM_mapallocN(allocsize, "ImaUndoRect");
 
384
 
 
385
        undo_copy_tile(tile, *tmpibuf, ibuf, 0);
 
386
        curundo->undosize += allocsize;
 
387
 
 
388
        BLI_addtail(&curundo->tiles, tile);
 
389
        
 
390
        return tile;
 
391
}
 
392
 
172
393
static void undo_restore(UndoElem *undo)
173
394
{
174
395
        Image *ima = NULL;
257
478
static void undo_imagepaint_push_end()
258
479
{
259
480
        UndoElem *uel;
260
 
        unsigned long totmem, maxmem;
 
481
        uintptr_t totmem, maxmem;
261
482
 
262
483
        if(U.undomemory != 0) {
263
484
                /* limit to maximum memory (afterwards, we can't know in advance) */
264
485
                totmem= 0;
265
 
                maxmem= ((unsigned long)U.undomemory)*1024*1024;
 
486
                maxmem= ((uintptr_t)U.undomemory)*1024*1024;
266
487
 
267
488
                uel= undobase.last;
268
489
                while(uel) {
281
502
        }
282
503
}
283
504
 
284
 
/* external functions */
 
505
/* fast projection bucket array lookup, use the safe version for bound checking  */
 
506
static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2])
 
507
{
 
508
        /* If we were not dealing with screenspace 2D coords we could simple do...
 
509
         * ps->bucketRect[x + (y*ps->buckets_y)] */
 
510
        
 
511
        /* please explain?
 
512
         * projCoSS[0] - ps->screenMin[0]       : zero origin
 
513
         * ... / ps->screen_width                               : range from 0.0 to 1.0
 
514
         * ... * ps->buckets_x          : use as a bucket index
 
515
         *
 
516
         * Second multiplication does similar but for vertical offset
 
517
         */
 
518
        return  (       (int)(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width)  * ps->buckets_x)) + 
 
519
                (       (       (int)(((projCoSS[1] - ps->screenMin[1])  / ps->screen_height) * ps->buckets_y)) * ps->buckets_x);
 
520
}
 
521
 
 
522
static int project_bucket_offset_safe(const ProjPaintState *ps, const float projCoSS[2])
 
523
{
 
524
        int bucket_index = project_bucket_offset(ps, projCoSS);
 
525
        
 
526
        if (bucket_index < 0 || bucket_index >= ps->buckets_x*ps->buckets_y) {  
 
527
                return -1;
 
528
        }
 
529
        else {
 
530
                return bucket_index;
 
531
        }
 
532
}
 
533
 
 
534
#define SIDE_OF_LINE(pa, pb, pp)        ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
 
535
 
 
536
static float AreaSignedF2Dfl(float *v1, float *v2, float *v3)
 
537
{
 
538
   return (float)(0.5f*((v1[0]-v2[0])*(v2[1]-v3[1]) +
 
539
(v1[1]-v2[1])*(v3[0]-v2[0])));
 
540
}
 
541
 
 
542
static void BarycentricWeights2f(float pt[2], float v1[2], float v2[2], float v3[2], float w[3])
 
543
{
 
544
   float wtot_inv, wtot;
 
545
 
 
546
   w[0] = AreaSignedF2Dfl(v2, v3, pt);
 
547
   w[1] = AreaSignedF2Dfl(v3, v1, pt);
 
548
   w[2] = AreaSignedF2Dfl(v1, v2, pt);
 
549
   wtot = w[0]+w[1]+w[2];
 
550
 
 
551
   if (wtot != 0.0f) {
 
552
       wtot_inv = 1.0f/wtot;
 
553
 
 
554
       w[0] = w[0]*wtot_inv;
 
555
       w[1] = w[1]*wtot_inv;
 
556
       w[2] = w[2]*wtot_inv;
 
557
   }
 
558
   else /* dummy values for zero area face */
 
559
       w[0] = w[1] = w[2] = 1.0f/3.0f;
 
560
}
 
561
 
 
562
/* still use 2D X,Y space but this works for verts transformed by a perspective matrix, using their 4th component as a weight */
 
563
static void BarycentricWeightsPersp2f(float pt[2], float v1[4], float v2[4], float v3[4], float w[3])
 
564
{
 
565
   float wtot_inv, wtot;
 
566
 
 
567
   w[0] = AreaSignedF2Dfl(v2, v3, pt) / v1[3];
 
568
   w[1] = AreaSignedF2Dfl(v3, v1, pt) / v2[3];
 
569
   w[2] = AreaSignedF2Dfl(v1, v2, pt) / v3[3];
 
570
   wtot = w[0]+w[1]+w[2];
 
571
 
 
572
   if (wtot != 0.0f) {
 
573
       wtot_inv = 1.0f/wtot;
 
574
 
 
575
       w[0] = w[0]*wtot_inv;
 
576
       w[1] = w[1]*wtot_inv;
 
577
       w[2] = w[2]*wtot_inv;
 
578
   }
 
579
   else /* dummy values for zero area face */
 
580
       w[0] = w[1] = w[2] = 1.0f/3.0f;
 
581
}
 
582
 
 
583
static void VecWeightf(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
 
584
{
 
585
        p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
 
586
        p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
 
587
        p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2];
 
588
}
 
589
 
 
590
static void Vec2Weightf(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3])
 
591
{
 
592
        p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
 
593
        p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
 
594
}
 
595
 
 
596
static float VecZDepthOrtho(float pt[2], float v1[3], float v2[3], float v3[3], float w[3])
 
597
{
 
598
        BarycentricWeights2f(pt, v1, v2, v3, w);
 
599
        return (v1[2]*w[0]) + (v2[2]*w[1]) + (v3[2]*w[2]);
 
600
}
 
601
 
 
602
static float VecZDepthPersp(float pt[2], float v1[3], float v2[3], float v3[3], float w[3])
 
603
{
 
604
        BarycentricWeightsPersp2f(pt, v1, v2, v3, w);
 
605
        return (v1[2]*w[0]) + (v2[2]*w[1]) + (v3[2]*w[2]);
 
606
}
 
607
 
 
608
 
 
609
/* Return the top-most face index that the screen space coord 'pt' touches (or -1) */
 
610
static int project_paint_PickFace(const ProjPaintState *ps, float pt[2], float w[3], int *side)
 
611
{
 
612
        LinkNode *node;
 
613
        float w_tmp[3];
 
614
        float *v1, *v2, *v3, *v4;
 
615
        int bucket_index;
 
616
        int face_index;
 
617
        int best_side = -1;
 
618
        int best_face_index = -1;
 
619
        float z_depth_best = MAXFLOAT, z_depth;
 
620
        MFace *mf;
 
621
        
 
622
        bucket_index = project_bucket_offset_safe(ps, pt);
 
623
        if (bucket_index==-1)
 
624
                return -1;
 
625
        
 
626
        
 
627
        
 
628
        /* we could return 0 for 1 face buckets, as long as this function assumes
 
629
         * that the point its testing is only every originated from an existing face */
 
630
        
 
631
        for (node= ps->bucketFaces[bucket_index]; node; node= node->next) {
 
632
                face_index = GET_INT_FROM_POINTER(node->link);
 
633
                mf= ps->dm_mface + face_index;
 
634
                
 
635
                v1= ps->screenCoords[mf->v1];
 
636
                v2= ps->screenCoords[mf->v2];
 
637
                v3= ps->screenCoords[mf->v3];
 
638
                
 
639
                if (IsectPT2Df(pt, v1, v2, v3)) {
 
640
                        if (ps->is_ortho)       z_depth= VecZDepthOrtho(pt, v1, v2, v3, w_tmp);
 
641
                        else                            z_depth= VecZDepthPersp(pt, v1, v2, v3, w_tmp);
 
642
                        
 
643
                        if (z_depth < z_depth_best) {
 
644
                                best_face_index = face_index;
 
645
                                best_side = 0;
 
646
                                z_depth_best = z_depth;
 
647
                                VECCOPY(w, w_tmp);
 
648
                        }
 
649
                }
 
650
                else if (mf->v4) {
 
651
                        v4= ps->screenCoords[mf->v4];
 
652
                        
 
653
                        if (IsectPT2Df(pt, v1, v3, v4)) {
 
654
                                if (ps->is_ortho)       z_depth= VecZDepthOrtho(pt, v1, v3, v4, w_tmp);
 
655
                                else                            z_depth= VecZDepthPersp(pt, v1, v3, v4, w_tmp);
 
656
 
 
657
                                if (z_depth < z_depth_best) {
 
658
                                        best_face_index = face_index;
 
659
                                        best_side= 1;
 
660
                                        z_depth_best = z_depth;
 
661
                                        VECCOPY(w, w_tmp);
 
662
                                }
 
663
                        }
 
664
                }
 
665
        }
 
666
        
 
667
        *side = best_side;
 
668
        return best_face_index; /* will be -1 or a valid face */
 
669
}
 
670
 
 
671
/* Converts a uv coord into a pixel location wrapping if the uv is outside 0-1 range */
 
672
static void uvco_to_wrapped_pxco(float uv[2], int ibuf_x, int ibuf_y, float *x, float *y)
 
673
{
 
674
        /* use */
 
675
        *x = (float)fmodf(uv[0], 1.0f);
 
676
        *y = (float)fmodf(uv[1], 1.0f);
 
677
        
 
678
        if (*x < 0.0f) *x += 1.0f;
 
679
        if (*y < 0.0f) *y += 1.0f;
 
680
        
 
681
        *x = *x * ibuf_x - 0.5f;
 
682
        *y = *y * ibuf_y - 0.5f;
 
683
}
 
684
 
 
685
/* Set the top-most face color that the screen space coord 'pt' touches (or return 0 if none touch) */
 
686
static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float *rgba_fp, unsigned char *rgba, const int interp)
 
687
{
 
688
        float w[3], uv[2];
 
689
        int side;
 
690
        int face_index;
 
691
        MTFace *tf;
 
692
        ImBuf *ibuf;
 
693
        int xi, yi;
 
694
        
 
695
        
 
696
        face_index = project_paint_PickFace(ps, pt, w, &side);
 
697
        
 
698
        if (face_index == -1)
 
699
                return 0;
 
700
        
 
701
        tf = ps->dm_mtface + face_index;
 
702
        
 
703
        if (side == 0) {
 
704
                Vec2Weightf(uv, tf->uv[0], tf->uv[1], tf->uv[2], w);
 
705
        }
 
706
        else { /* QUAD */
 
707
                Vec2Weightf(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
 
708
        }
 
709
        
 
710
        ibuf = tf->tpage->ibufs.first; /* we must have got the imbuf before getting here */
 
711
        if (!ibuf) return 0;
 
712
        
 
713
        if (interp) {
 
714
                float x, y;
 
715
                uvco_to_wrapped_pxco(uv, ibuf->x, ibuf->y, &x, &y);
 
716
                
 
717
                if (ibuf->rect_float) {
 
718
                        if (rgba_fp) {
 
719
                                bilinear_interpolation_color_wrap(ibuf, NULL, rgba_fp, x, y);
 
720
                        }
 
721
                        else {
 
722
                                float rgba_tmp_f[4];
 
723
                                bilinear_interpolation_color_wrap(ibuf, NULL, rgba_tmp_f, x, y);
 
724
                                IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_f);
 
725
                        }
 
726
                }
 
727
                else {
 
728
                        if (rgba) {
 
729
                                bilinear_interpolation_color_wrap(ibuf, rgba, NULL, x, y);
 
730
                        }
 
731
                        else {
 
732
                                unsigned char rgba_tmp[4];
 
733
                                bilinear_interpolation_color_wrap(ibuf, rgba_tmp, NULL, x, y);
 
734
                                IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, rgba_tmp);
 
735
                        }
 
736
                }
 
737
        }
 
738
        else {
 
739
                xi = (uv[0]*ibuf->x) + 0.5f;
 
740
                yi = (uv[1]*ibuf->y) + 0.5f;
 
741
                
 
742
                //if (xi<0 || xi>=ibuf->x  ||  yi<0 || yi>=ibuf->y) return 0;
 
743
                
 
744
                /* wrap */
 
745
                xi = ((int)(uv[0]*ibuf->x)) % ibuf->x;
 
746
                if (xi<0) xi += ibuf->x;
 
747
                yi = ((int)(uv[1]*ibuf->y)) % ibuf->y;
 
748
                if (yi<0) yi += ibuf->y;
 
749
                
 
750
                
 
751
                if (rgba) {
 
752
                        if (ibuf->rect_float) {
 
753
                                float *rgba_tmp_fp = ibuf->rect_float + (xi + yi * ibuf->x * 4);
 
754
                                IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_fp);
 
755
                        }
 
756
                        else {
 
757
                                *((unsigned int *)rgba) = *(unsigned int *)(((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4));
 
758
                        }
 
759
                }
 
760
                
 
761
                if (rgba_fp) {
 
762
                        if (ibuf->rect_float) {
 
763
                                QUATCOPY(rgba_fp, ((float *)ibuf->rect_float + ((xi + yi * ibuf->x) * 4)));
 
764
                        }
 
765
                        else {
 
766
                                char *tmp_ch= ((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4);
 
767
                                IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, tmp_ch);
 
768
                        }
 
769
                }
 
770
        }
 
771
        return 1;
 
772
}
 
773
 
 
774
/* Check if 'pt' is infront of the 3 verts on the Z axis (used for screenspace occlusuion test)
 
775
 * return...
 
776
 *  0   : no occlusion
 
777
 * -1   : no occlusion but 2D intersection is true (avoid testing the other half of a quad)
 
778
 *  1   : occluded
 
779
    2   : occluded with w[3] weights set (need to know in some cases) */
 
780
 
 
781
static int project_paint_occlude_ptv(float pt[3], float v1[3], float v2[3], float v3[3], float w[3], int is_ortho)
 
782
{
 
783
        /* if all are behind us, return false */
 
784
        if(v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2])
 
785
                return 0;
 
786
                
 
787
        /* do a 2D point in try intersection */
 
788
        if (!IsectPT2Df(pt, v1, v2, v3))
 
789
                return 0; /* we know there is  */
 
790
        
 
791
 
 
792
        /* From here on we know there IS an intersection */
 
793
        /* if ALL of the verts are infront of us then we know it intersects ? */
 
794
        if(v1[2] < pt[2] && v2[2] < pt[2] && v3[2] < pt[2]) {
 
795
                return 1;
 
796
        }
 
797
        else {
 
798
                /* we intersect? - find the exact depth at the point of intersection */
 
799
                /* Is this point is occluded by another face? */
 
800
                if (is_ortho) {
 
801
                        if (VecZDepthOrtho(pt, v1, v2, v3, w) < pt[2]) return 2;
 
802
                }
 
803
                else {
 
804
                        if (VecZDepthPersp(pt, v1, v2, v3, w) < pt[2]) return 2;
 
805
                }
 
806
        }
 
807
        return -1;
 
808
}
 
809
 
 
810
 
 
811
static int project_paint_occlude_ptv_clip(
 
812
                const ProjPaintState *ps, const MFace *mf,
 
813
                float pt[3], float v1[3], float v2[3], float v3[3],
 
814
                const int side )
 
815
{
 
816
        float w[3], wco[3];
 
817
        int ret = project_paint_occlude_ptv(pt, v1, v2, v3, w, ps->is_ortho);
 
818
 
 
819
        if (ret <= 0)
 
820
                return ret;
 
821
 
 
822
        if (ret==1) { /* weights not calculated */
 
823
                if (ps->is_ortho)       BarycentricWeights2f(pt, v1, v2, v3, w);
 
824
                else                            BarycentricWeightsPersp2f(pt, v1, v2, v3, w);
 
825
        }
 
826
 
 
827
        /* Test if we're in the clipped area, */
 
828
        if (side)       VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
 
829
        else            VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
 
830
        
 
831
        Mat4MulVecfl(ps->ob->obmat, wco);
 
832
        if(!view3d_test_clipping(G.vd, wco)) {
 
833
                return 1;
 
834
        }
 
835
        
 
836
        return -1;
 
837
}
 
838
 
 
839
 
 
840
/* Check if a screenspace location is occluded by any other faces
 
841
 * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison
 
842
 * and dosn't need to be correct in relation to X and Y coords (this is the case in perspective view) */
 
843
static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *bucketFace, const int orig_face, float pixelScreenCo[4])
 
844
{
 
845
        MFace *mf;
 
846
        int face_index;
 
847
        int isect_ret;
 
848
        float w[3]; /* not needed when clipping */
 
849
        
 
850
        /* we could return 0 for 1 face buckets, as long as this function assumes
 
851
         * that the point its testing is only every originated from an existing face */
 
852
 
 
853
        for (; bucketFace; bucketFace = bucketFace->next) {
 
854
                face_index = (int)bucketFace->link;
 
855
 
 
856
                if (orig_face != face_index) {
 
857
                        mf = ps->dm_mface + face_index;
 
858
                        if(G.vd->flag & V3D_CLIPPING)
 
859
                                isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], 0);
 
860
                        else
 
861
                                isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], w, ps->is_ortho);
 
862
 
 
863
                        /* Note, if isect_ret==-1 then we dont want to test the other side of the quad */
 
864
                        if (isect_ret==0 && mf->v4) {
 
865
                                if(G.vd->flag & V3D_CLIPPING)
 
866
                                        isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], 1);
 
867
                                else
 
868
                                        isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], w, ps->is_ortho);
 
869
                        }
 
870
                        if (isect_ret>=1) {
 
871
                                /* TODO - we may want to cache the first hit,
 
872
                                 * it is not possible to swap the face order in the list anymore */
 
873
                                return 1;
 
874
                        }
 
875
                }
 
876
        }
 
877
        return 0;
 
878
}
 
879
 
 
880
/* basic line intersection, could move to arithb.c, 2 points with a horiz line
 
881
 * 1 for an intersection, 2 if the first point is aligned, 3 if the second point is aligned */
 
882
#define ISECT_TRUE 1
 
883
#define ISECT_TRUE_P1 2
 
884
#define ISECT_TRUE_P2 3
 
885
static int line_isect_y(const float p1[2], const float p2[2], const float y_level, float *x_isect)
 
886
{
 
887
        float y_diff;
 
888
        
 
889
        if (y_level==p1[1]) { /* are we touching the first point? - no interpolation needed */
 
890
                *x_isect = p1[0];
 
891
                return ISECT_TRUE_P1;
 
892
        }
 
893
        if (y_level==p2[1]) { /* are we touching the second point? - no interpolation needed */
 
894
                *x_isect = p2[0];
 
895
                return ISECT_TRUE_P2;
 
896
        }
 
897
        
 
898
        y_diff= fabsf(p1[1]-p2[1]); /* yuck, horizontal line, we cant do much here */
 
899
        
 
900
        if (y_diff < 0.000001f) {
 
901
                *x_isect = (p1[0]+p2[0]) * 0.5f;
 
902
                return ISECT_TRUE;              
 
903
        }
 
904
        
 
905
        if (p1[1] > y_level && p2[1] < y_level) {
 
906
                *x_isect = (p2[0]*(p1[1]-y_level) + p1[0]*(y_level-p2[1])) / y_diff;  /*(p1[1]-p2[1]);*/
 
907
                return ISECT_TRUE;
 
908
        }
 
909
        else if (p1[1] < y_level && p2[1] > y_level) {
 
910
                *x_isect = (p2[0]*(y_level-p1[1]) + p1[0]*(p2[1]-y_level)) / y_diff;  /*(p2[1]-p1[1]);*/
 
911
                return ISECT_TRUE;
 
912
        }
 
913
        else {
 
914
                return 0;
 
915
        }
 
916
}
 
917
 
 
918
static int line_isect_x(const float p1[2], const float p2[2], const float x_level, float *y_isect)
 
919
{
 
920
        float x_diff;
 
921
        
 
922
        if (x_level==p1[0]) { /* are we touching the first point? - no interpolation needed */
 
923
                *y_isect = p1[1];
 
924
                return ISECT_TRUE_P1;
 
925
        }
 
926
        if (x_level==p2[0]) { /* are we touching the second point? - no interpolation needed */
 
927
                *y_isect = p2[1];
 
928
                return ISECT_TRUE_P2;
 
929
        }
 
930
        
 
931
        x_diff= fabsf(p1[0]-p2[0]); /* yuck, horizontal line, we cant do much here */
 
932
        
 
933
        if (x_diff < 0.000001) { /* yuck, vertical line, we cant do much here */
 
934
                *y_isect = (p1[0]+p2[0]) * 0.5f;
 
935
                return ISECT_TRUE;              
 
936
        }
 
937
        
 
938
        if (p1[0] > x_level && p2[0] < x_level) {
 
939
                *y_isect = (p2[1]*(p1[0]-x_level) + p1[1]*(x_level-p2[0])) / x_diff; /*(p1[0]-p2[0]);*/
 
940
                return ISECT_TRUE;
 
941
        }
 
942
        else if (p1[0] < x_level && p2[0] > x_level) {
 
943
                *y_isect = (p2[1]*(x_level-p1[0]) + p1[1]*(p2[0]-x_level)) / x_diff; /*(p2[0]-p1[0]);*/
 
944
                return ISECT_TRUE;
 
945
        }
 
946
        else {
 
947
                return 0;
 
948
        }
 
949
}
 
950
 
 
951
/* simple func use for comparing UV locations to check if there are seams.
 
952
 * Its possible this gives incorrect results, when the UVs for 1 face go into the next 
 
953
 * tile, but do not do this for the adjacent face, it could return a false positive.
 
954
 * This is so unlikely that Id not worry about it. */
 
955
#ifndef PROJ_DEBUG_NOSEAMBLEED
 
956
static int cmp_uv(const float vec2a[2], const float vec2b[2])
 
957
{
 
958
        /* if the UV's are not between 0.0 and 1.0 */
 
959
        float xa = (float)fmodf(vec2a[0], 1.0f);
 
960
        float ya = (float)fmodf(vec2a[1], 1.0f);
 
961
        
 
962
        float xb = (float)fmodf(vec2b[0], 1.0f);
 
963
        float yb = (float)fmodf(vec2b[1], 1.0f);        
 
964
        
 
965
        if (xa < 0.0f) xa += 1.0f;
 
966
        if (ya < 0.0f) ya += 1.0f;
 
967
        
 
968
        if (xb < 0.0f) xb += 1.0f;
 
969
        if (yb < 0.0f) yb += 1.0f;
 
970
        
 
971
        return ((fabsf(xa-xb) < PROJ_GEOM_TOLERANCE) && (fabsf(ya-yb) < PROJ_GEOM_TOLERANCE)) ? 1:0;
 
972
}
 
973
#endif
 
974
 
 
975
/* set min_px and max_px to the image space bounds of the UV coords 
 
976
 * return zero if there is no area in the returned rectangle */
 
977
#ifndef PROJ_DEBUG_NOSEAMBLEED
 
978
static int pixel_bounds_uv(
 
979
                const float uv1[2], const float uv2[2], const float uv3[2], const float uv4[2],
 
980
                rcti *bounds_px,
 
981
                const int ibuf_x, const int ibuf_y,
 
982
                int is_quad
 
983
) {
 
984
        float min_uv[2], max_uv[2]; /* UV bounds */
 
985
        
 
986
        INIT_MINMAX2(min_uv, max_uv);
 
987
        
 
988
        DO_MINMAX2(uv1, min_uv, max_uv);
 
989
        DO_MINMAX2(uv2, min_uv, max_uv);
 
990
        DO_MINMAX2(uv3, min_uv, max_uv);
 
991
        if (is_quad)
 
992
                DO_MINMAX2(uv4, min_uv, max_uv);
 
993
        
 
994
        bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
 
995
        bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
 
996
        
 
997
        bounds_px->xmax = (int)(ibuf_x * max_uv[0]) +1;
 
998
        bounds_px->ymax = (int)(ibuf_y * max_uv[1]) +1;
 
999
        
 
1000
        /*printf("%d %d %d %d \n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
 
1001
        
 
1002
        /* face uses no UV area when quantized to pixels? */
 
1003
        return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
 
1004
}
 
1005
#endif
 
1006
 
 
1007
static int pixel_bounds_array(float (* uv)[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, int tot)
 
1008
{
 
1009
        float min_uv[2], max_uv[2]; /* UV bounds */
 
1010
        
 
1011
        if (tot==0) {
 
1012
                return 0;
 
1013
        }
 
1014
        
 
1015
        INIT_MINMAX2(min_uv, max_uv);
 
1016
        
 
1017
        while (tot--) {
 
1018
                DO_MINMAX2((*uv), min_uv, max_uv);
 
1019
                uv++;
 
1020
        }
 
1021
        
 
1022
        bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
 
1023
        bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
 
1024
        
 
1025
        bounds_px->xmax = (int)(ibuf_x * max_uv[0]) +1;
 
1026
        bounds_px->ymax = (int)(ibuf_y * max_uv[1]) +1;
 
1027
        
 
1028
        /*printf("%d %d %d %d \n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
 
1029
        
 
1030
        /* face uses no UV area when quantized to pixels? */
 
1031
        return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
 
1032
}
 
1033
 
 
1034
#ifndef PROJ_DEBUG_NOSEAMBLEED
 
1035
 
 
1036
/* This function returns 1 if this face has a seam along the 2 face-vert indicies
 
1037
 * 'orig_i1_fidx' and 'orig_i2_fidx' */
 
1038
static int check_seam(const ProjPaintState *ps, const int orig_face, const int orig_i1_fidx, const int orig_i2_fidx, int *other_face, int *orig_fidx)
 
1039
{
 
1040
        LinkNode *node;
 
1041
        int face_index;
 
1042
        int i1, i2;
 
1043
        int i1_fidx = -1, i2_fidx = -1; /* index in face */
 
1044
        MFace *mf;
 
1045
        MTFace *tf;
 
1046
        const MFace *orig_mf = ps->dm_mface + orig_face;  
 
1047
        const MTFace *orig_tf = ps->dm_mtface + orig_face;
 
1048
        
 
1049
        /* vert indicies from face vert order indicies */
 
1050
        i1 = (*(&orig_mf->v1 + orig_i1_fidx));
 
1051
        i2 = (*(&orig_mf->v1 + orig_i2_fidx));
 
1052
        
 
1053
        for (node = ps->vertFaces[i1]; node; node = node->next) {
 
1054
                face_index = (int)node->link;
 
1055
                if (face_index != orig_face) {
 
1056
                        mf = ps->dm_mface + face_index;
 
1057
                        /* could check if the 2 faces images match here,
 
1058
                         * but then there wouldn't be a way to return the opposite face's info */
 
1059
                        
 
1060
                        
 
1061
                        /* We need to know the order of the verts in the adjacent face 
 
1062
                         * set the i1_fidx and i2_fidx to (0,1,2,3) */
 
1063
                        if              (mf->v1==i1)                    i1_fidx = 0;
 
1064
                        else if (mf->v2==i1)                    i1_fidx = 1;
 
1065
                        else if (mf->v3==i1)                    i1_fidx = 2;
 
1066
                        else if (mf->v4 && mf->v4==i1)  i1_fidx = 3;
 
1067
                        
 
1068
                        if              (mf->v1==i2)                    i2_fidx = 0;
 
1069
                        else if (mf->v2==i2)                    i2_fidx = 1;
 
1070
                        else if (mf->v3==i2)                    i2_fidx = 2;
 
1071
                        else if (mf->v4 && mf->v4==i2)  i2_fidx = 3;
 
1072
                        
 
1073
                        /* Only need to check if 'i2_fidx' is valid because we know i1_fidx is the same vert on both faces */
 
1074
                        if (i2_fidx != -1) {
 
1075
                                /* This IS an adjacent face!, now lets check if the UVs are ok */
 
1076
                                tf = ps->dm_mtface + face_index;
 
1077
                                
 
1078
                                /* set up the other face */
 
1079
                                *other_face = face_index;
 
1080
                                *orig_fidx = (i1_fidx < i2_fidx) ? i1_fidx : i2_fidx;
 
1081
                                
 
1082
                                /* first test if they have the same image */
 
1083
                                if (    (orig_tf->tpage == tf->tpage) &&
 
1084
                                                cmp_uv(orig_tf->uv[orig_i1_fidx], tf->uv[i1_fidx]) &&
 
1085
                                                cmp_uv(orig_tf->uv[orig_i2_fidx], tf->uv[i2_fidx]) )
 
1086
                                {
 
1087
                                        // printf("SEAM (NONE)\n");
 
1088
                                        return 0;
 
1089
                                        
 
1090
                                }
 
1091
                                else {
 
1092
                                        // printf("SEAM (UV GAP)\n");
 
1093
                                        return 1;
 
1094
                                }
 
1095
                        }
 
1096
                }
 
1097
        }
 
1098
        // printf("SEAM (NO FACE)\n");
 
1099
        *other_face = -1;
 
1100
        return 1;
 
1101
}
 
1102
 
 
1103
/* TODO - move to arithb.c */
 
1104
/* Converts an angle to a length that can be used for maintaining an even margin around UV's */
 
1105
static float angleToLength(float angle)
 
1106
{
 
1107
        // already accounted for
 
1108
        if (angle < 0.000001f) {
 
1109
                return 1.0f;
 
1110
        }
 
1111
        else {
 
1112
                return fabsf(1.0f / cosf(angle * (M_PI/180.0f)));
 
1113
        }
 
1114
}
 
1115
 
 
1116
/* Calculate outset UV's, this is not the same as simply scaling the UVs,
 
1117
 * since the outset coords are a margin that keep an even distance from the original UV's,
 
1118
 * note that the image aspect is taken into account */
 
1119
static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const float scaler, const int ibuf_x, const int ibuf_y, const int is_quad)
 
1120
{
 
1121
        float a1, a2, a3, a4=0.0f;
 
1122
        float puv[4][2]; /* pixelspace uv's */
 
1123
        float no1[2], no2[2], no3[2], no4[2]; /* normals */
 
1124
        float dir1[2], dir2[2], dir3[2], dir4[2];
 
1125
        float ibuf_x_inv = 1.0f / (float)ibuf_x; 
 
1126
        float ibuf_y_inv = 1.0f / (float)ibuf_y; 
 
1127
        
 
1128
        /* make UV's in pixel space so we can */
 
1129
        puv[0][0] = orig_uv[0][0] * ibuf_x;
 
1130
        puv[0][1] = orig_uv[0][1] * ibuf_y;
 
1131
        
 
1132
        puv[1][0] = orig_uv[1][0] * ibuf_x;
 
1133
        puv[1][1] = orig_uv[1][1] * ibuf_y;
 
1134
        
 
1135
        puv[2][0] = orig_uv[2][0] * ibuf_x;
 
1136
        puv[2][1] = orig_uv[2][1] * ibuf_y;
 
1137
        
 
1138
        if (is_quad) {
 
1139
                puv[3][0] = orig_uv[3][0] * ibuf_x;
 
1140
                puv[3][1] = orig_uv[3][1] * ibuf_y;
 
1141
        }
 
1142
        
 
1143
        /* face edge directions */
 
1144
        Vec2Subf(dir1, puv[1], puv[0]);
 
1145
        Vec2Subf(dir2, puv[2], puv[1]);
 
1146
        Normalize2(dir1);
 
1147
        Normalize2(dir2);
 
1148
        
 
1149
        if (is_quad) {
 
1150
                Vec2Subf(dir3, puv[3], puv[2]);
 
1151
                Vec2Subf(dir4, puv[0], puv[3]);
 
1152
                Normalize2(dir3);
 
1153
                Normalize2(dir4);
 
1154
        }
 
1155
        else {
 
1156
                Vec2Subf(dir3, puv[0], puv[2]);
 
1157
                Normalize2(dir3);
 
1158
        }
 
1159
        
 
1160
        if (is_quad) {
 
1161
                a1 = angleToLength(NormalizedVecAngle2_2D(dir4, dir1));
 
1162
                a2 = angleToLength(NormalizedVecAngle2_2D(dir1, dir2));
 
1163
                a3 = angleToLength(NormalizedVecAngle2_2D(dir2, dir3));
 
1164
                a4 = angleToLength(NormalizedVecAngle2_2D(dir3, dir4));
 
1165
        }
 
1166
        else {
 
1167
                a1 = angleToLength(NormalizedVecAngle2_2D(dir3, dir1));
 
1168
                a2 = angleToLength(NormalizedVecAngle2_2D(dir1, dir2));
 
1169
                a3 = angleToLength(NormalizedVecAngle2_2D(dir2, dir3));
 
1170
        }
 
1171
        
 
1172
        if (is_quad) {
 
1173
                Vec2Subf(no1, dir4, dir1);
 
1174
                Vec2Subf(no2, dir1, dir2);
 
1175
                Vec2Subf(no3, dir2, dir3);
 
1176
                Vec2Subf(no4, dir3, dir4);
 
1177
                Normalize2(no1);
 
1178
                Normalize2(no2);
 
1179
                Normalize2(no3);
 
1180
                Normalize2(no4);
 
1181
                Vec2Mulf(no1, a1*scaler);
 
1182
                Vec2Mulf(no2, a2*scaler);
 
1183
                Vec2Mulf(no3, a3*scaler);
 
1184
                Vec2Mulf(no4, a4*scaler);
 
1185
                Vec2Addf(outset_uv[0], puv[0], no1);
 
1186
                Vec2Addf(outset_uv[1], puv[1], no2);
 
1187
                Vec2Addf(outset_uv[2], puv[2], no3);
 
1188
                Vec2Addf(outset_uv[3], puv[3], no4);
 
1189
                outset_uv[0][0] *= ibuf_x_inv;
 
1190
                outset_uv[0][1] *= ibuf_y_inv;
 
1191
                
 
1192
                outset_uv[1][0] *= ibuf_x_inv;
 
1193
                outset_uv[1][1] *= ibuf_y_inv;
 
1194
                
 
1195
                outset_uv[2][0] *= ibuf_x_inv;
 
1196
                outset_uv[2][1] *= ibuf_y_inv;
 
1197
                
 
1198
                outset_uv[3][0] *= ibuf_x_inv;
 
1199
                outset_uv[3][1] *= ibuf_y_inv;
 
1200
        }
 
1201
        else {
 
1202
                Vec2Subf(no1, dir3, dir1);
 
1203
                Vec2Subf(no2, dir1, dir2);
 
1204
                Vec2Subf(no3, dir2, dir3);
 
1205
                Normalize2(no1);
 
1206
                Normalize2(no2);
 
1207
                Normalize2(no3);
 
1208
                Vec2Mulf(no1, a1*scaler);
 
1209
                Vec2Mulf(no2, a2*scaler);
 
1210
                Vec2Mulf(no3, a3*scaler);
 
1211
                Vec2Addf(outset_uv[0], puv[0], no1);
 
1212
                Vec2Addf(outset_uv[1], puv[1], no2);
 
1213
                Vec2Addf(outset_uv[2], puv[2], no3);
 
1214
                outset_uv[0][0] *= ibuf_x_inv;
 
1215
                outset_uv[0][1] *= ibuf_y_inv;
 
1216
                
 
1217
                outset_uv[1][0] *= ibuf_x_inv;
 
1218
                outset_uv[1][1] *= ibuf_y_inv;
 
1219
                
 
1220
                outset_uv[2][0] *= ibuf_x_inv;
 
1221
                outset_uv[2][1] *= ibuf_y_inv;
 
1222
        }
 
1223
}
 
1224
 
 
1225
/* 
 
1226
 * Be tricky with flags, first 4 bits are PROJ_FACE_SEAM1 to 4, last 4 bits are PROJ_FACE_NOSEAM1 to 4
 
1227
 * 1<<i - where i is (0-3) 
 
1228
 * 
 
1229
 * If we're multithreadng, make sure threads are locked when this is called
 
1230
 */
 
1231
static void project_face_seams_init(const ProjPaintState *ps, const int face_index, const int is_quad)
 
1232
{
 
1233
        int other_face, other_fidx; /* vars for the other face, we also set its flag */
 
1234
        int fidx1 = is_quad ? 3 : 2;
 
1235
        int fidx2 = 0; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) or (0,1,2) -> (1,2,0) for a tri */
 
1236
        
 
1237
        do {
 
1238
                if ((ps->faceSeamFlags[face_index] & (1<<fidx1|16<<fidx1)) == 0) {
 
1239
                        if (check_seam(ps, face_index, fidx1, fidx2, &other_face, &other_fidx)) {
 
1240
                                ps->faceSeamFlags[face_index] |= 1<<fidx1;
 
1241
                                if (other_face != -1)
 
1242
                                        ps->faceSeamFlags[other_face] |= 1<<other_fidx;
 
1243
                        }
 
1244
                        else {
 
1245
                                ps->faceSeamFlags[face_index] |= 16<<fidx1;
 
1246
                                if (other_face != -1)
 
1247
                                        ps->faceSeamFlags[other_face] |= 16<<other_fidx; /* second 4 bits for disabled */
 
1248
                        }
 
1249
                }
 
1250
                
 
1251
                fidx2 = fidx1;
 
1252
        } while (fidx1--);
 
1253
}
 
1254
#endif // PROJ_DEBUG_NOSEAMBLEED
 
1255
 
 
1256
 
 
1257
/* TODO - move to arithb.c */
 
1258
 
 
1259
/* little sister we only need to know lambda */
 
1260
static float lambda_cp_line2(const float p[2], const float l1[2], const float l2[2])
 
1261
{
 
1262
        float h[2], u[2];
 
1263
        
 
1264
        u[0] = l2[0] - l1[0];
 
1265
        u[1] = l2[1] - l1[1];
 
1266
 
 
1267
        h[0] = p[0] - l1[0];
 
1268
        h[1] = p[1] - l1[1];
 
1269
        
 
1270
        return(Inp2f(u, h)/Inp2f(u, u));
 
1271
}
 
1272
 
 
1273
 
 
1274
/* Converts a UV location to a 3D screenspace location
 
1275
 * Takes a 'uv' and 3 UV coords, and sets the values of pixelScreenCo
 
1276
 * 
 
1277
 * This is used for finding a pixels location in screenspace for painting */
 
1278
static void screen_px_from_ortho(
 
1279
                float uv[2],
 
1280
                float v1co[3], float v2co[3], float v3co[3], /* Screenspace coords */
 
1281
                float uv1co[2], float uv2co[2], float uv3co[2],
 
1282
                float pixelScreenCo[4],
 
1283
                float w[3])
 
1284
{
 
1285
        BarycentricWeights2f(uv, uv1co, uv2co, uv3co, w);
 
1286
        VecWeightf(pixelScreenCo, v1co, v2co, v3co, w);
 
1287
}
 
1288
 
 
1289
/* same as screen_px_from_ortho except we need to take into account
 
1290
 * the perspective W coord for each vert */
 
1291
static void screen_px_from_persp(
 
1292
                float uv[2],
 
1293
                float v1co[3], float v2co[3], float v3co[3], /* screenspace coords */
 
1294
                float uv1co[2], float uv2co[2], float uv3co[2],
 
1295
                float pixelScreenCo[4],
 
1296
                float w[3])
 
1297
{
 
1298
 
 
1299
        float wtot_inv, wtot;
 
1300
        BarycentricWeights2f(uv, uv1co, uv2co, uv3co, w);
 
1301
        
 
1302
        /* re-weight from the 4th coord of each screen vert */
 
1303
        w[0] *= v1co[3];
 
1304
        w[1] *= v2co[3];
 
1305
        w[2] *= v3co[3];
 
1306
        
 
1307
        wtot = w[0]+w[1]+w[2];
 
1308
        
 
1309
        if (wtot > 0.0f) {
 
1310
                wtot_inv = 1.0f / wtot;
 
1311
                w[0] *= wtot_inv;
 
1312
                w[1] *= wtot_inv;
 
1313
                w[2] *= wtot_inv;
 
1314
        }
 
1315
        else {
 
1316
                w[0] = w[1] = w[2] = 1.0/3.0; /* dummy values for zero area face */
 
1317
        }
 
1318
        /* done re-weighting */
 
1319
        
 
1320
        VecWeightf(pixelScreenCo, v1co, v2co, v3co, w);
 
1321
}
 
1322
 
 
1323
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])
 
1324
{
 
1325
        float *uvCo1, *uvCo2, *uvCo3;
 
1326
        float uv_other[2], x, y;
 
1327
        
 
1328
        uvCo1 =  (float *)tf_other->uv[0];
 
1329
        if (side==1) {
 
1330
                uvCo2 =  (float *)tf_other->uv[2];
 
1331
                uvCo3 =  (float *)tf_other->uv[3];
 
1332
        }
 
1333
        else {
 
1334
                uvCo2 =  (float *)tf_other->uv[1];
 
1335
                uvCo3 =  (float *)tf_other->uv[2];
 
1336
        }
 
1337
        
 
1338
        Vec2Weightf(uv_other, uvCo1, uvCo2, uvCo3, w);
 
1339
        
 
1340
        /* use */
 
1341
        uvco_to_wrapped_pxco(uv_other, ibuf_other->x, ibuf_other->y, &x, &y);
 
1342
        
 
1343
        
 
1344
        if (ibuf_other->rect_float) { /* from float to float */
 
1345
                bilinear_interpolation_color_wrap(ibuf_other, NULL, rgba_f, x, y);
 
1346
        }
 
1347
        else { /* from char to float */
 
1348
                bilinear_interpolation_color_wrap(ibuf_other, rgba_ub, NULL, x, y);
 
1349
        }
 
1350
                
 
1351
}
 
1352
 
 
1353
/* run this outside project_paint_uvpixel_init since pixels with mask 0 dont need init */
 
1354
float project_paint_uvpixel_mask(
 
1355
                const ProjPaintState *ps,
 
1356
                const int face_index,
 
1357
                const int side,
 
1358
                const float w[3])
 
1359
{
 
1360
        float mask;
 
1361
        
 
1362
        /* Image Mask */
 
1363
        if (ps->do_layer_mask) {
 
1364
                /* another UV layers image is masking this one's */
 
1365
                ImBuf *ibuf_other;
 
1366
                const MTFace *tf_other = ps->dm_mtface_mask + face_index;
 
1367
                
 
1368
                if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf(tf_other->tpage, NULL))) {
 
1369
                        /* BKE_image_get_ibuf - TODO - this may be slow */
 
1370
                        unsigned char rgba_ub[4];
 
1371
                        float rgba_f[4];
 
1372
                        
 
1373
                        project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, rgba_f);
 
1374
                        
 
1375
                        if (ibuf_other->rect_float) { /* from float to float */
 
1376
                                mask = ((rgba_f[0]+rgba_f[1]+rgba_f[2])/3.0f) * rgba_f[3];
 
1377
                        }
 
1378
                        else { /* from char to float */
 
1379
                                mask = ((rgba_ub[0]+rgba_ub[1]+rgba_ub[2])/(256*3.0f)) * (rgba_ub[3]/256.0f);
 
1380
                        }
 
1381
                        
 
1382
                        if (!ps->do_layer_mask_inv) /* matching the gimps layer mask black/white rules, white==full opacity */
 
1383
                                mask = (1.0f - mask);
 
1384
 
 
1385
                        if (mask == 0.0f) {
 
1386
                                return 0.0f;
 
1387
                        }
 
1388
                }
 
1389
                else {
 
1390
                        return 0.0f;
 
1391
                }
 
1392
        } else {
 
1393
                mask = 1.0f;
 
1394
        }
 
1395
        
 
1396
        /* calculate mask */
 
1397
        if (ps->do_mask_normal) {
 
1398
                MFace *mf = ps->dm_mface + face_index;
 
1399
                short *no1, *no2, *no3;
 
1400
                float no[3], angle;
 
1401
                no1 = ps->dm_mvert[mf->v1].no;
 
1402
                if (side==1) {
 
1403
                        no2 = ps->dm_mvert[mf->v3].no;
 
1404
                        no3 = ps->dm_mvert[mf->v4].no;
 
1405
                }
 
1406
                else {
 
1407
                        no2 = ps->dm_mvert[mf->v2].no;
 
1408
                        no3 = ps->dm_mvert[mf->v3].no;
 
1409
                }
 
1410
                
 
1411
                no[0] = w[0]*no1[0] + w[1]*no2[0] + w[2]*no3[0];
 
1412
                no[1] = w[0]*no1[1] + w[1]*no2[1] + w[2]*no3[1];
 
1413
                no[2] = w[0]*no1[2] + w[1]*no2[2] + w[2]*no3[2];
 
1414
                Normalize(no);
 
1415
                
 
1416
                /* now we can use the normal as a mask */
 
1417
                if (ps->is_ortho) {
 
1418
                        angle = NormalizedVecAngle2((float *)ps->viewDir, no);
 
1419
                }
 
1420
                else {
 
1421
                        /* Annoying but for the perspective view we need to get the pixels location in 3D space :/ */
 
1422
                        float viewDirPersp[3];
 
1423
                        float *co1, *co2, *co3;
 
1424
                        co1 = ps->dm_mvert[mf->v1].co;
 
1425
                        if (side==1) {
 
1426
                                co2 = ps->dm_mvert[mf->v3].co;
 
1427
                                co3 = ps->dm_mvert[mf->v4].co;
 
1428
                        }
 
1429
                        else {
 
1430
                                co2 = ps->dm_mvert[mf->v2].co;
 
1431
                                co3 = ps->dm_mvert[mf->v3].co;
 
1432
                        }
 
1433
 
 
1434
                        /* Get the direction from the viewPoint to the pixel and normalize */
 
1435
                        viewDirPersp[0] = (ps->viewPos[0] - (w[0]*co1[0] + w[1]*co2[0] + w[2]*co3[0]));
 
1436
                        viewDirPersp[1] = (ps->viewPos[1] - (w[0]*co1[1] + w[1]*co2[1] + w[2]*co3[1]));
 
1437
                        viewDirPersp[2] = (ps->viewPos[2] - (w[0]*co1[2] + w[1]*co2[2] + w[2]*co3[2]));
 
1438
                        Normalize(viewDirPersp);
 
1439
                        
 
1440
                        angle = NormalizedVecAngle2(viewDirPersp, no);
 
1441
                }
 
1442
                
 
1443
                if (angle >= ps->normal_angle) {
 
1444
                        return 0.0f; /* outsize the normal limit*/
 
1445
                }
 
1446
                else if (angle > ps->normal_angle_inner) {
 
1447
                        mask *= (ps->normal_angle - angle) / ps->normal_angle_range;
 
1448
                } /* otherwise no mask normal is needed, were within the limit */
 
1449
        }
 
1450
        
 
1451
        // This only works when the opacity dosnt change while painting, stylus pressure messes with this
 
1452
        // so dont use it.
 
1453
        // if (ps->is_airbrush==0) mask *= ps->brush->alpha;
 
1454
        
 
1455
        return mask;
 
1456
}
 
1457
 
 
1458
/* run this function when we know a bucket's, face's pixel can be initialized,
 
1459
 * return the ProjPixel which is added to 'ps->bucketRect[bucket_index]' */
 
1460
static ProjPixel *project_paint_uvpixel_init(
 
1461
                const ProjPaintState *ps,
 
1462
                MemArena *arena,
 
1463
                const ImBuf *ibuf,
 
1464
                short x_px, short y_px,
 
1465
                const float mask,
 
1466
                const int face_index,
 
1467
                const int image_index,
 
1468
                const float pixelScreenCo[4],
 
1469
                const int side,
 
1470
                const float w[3])
 
1471
{
 
1472
        ProjPixel *projPixel;
 
1473
        short size;
 
1474
        
 
1475
        /* wrap pixel location */
 
1476
        x_px = x_px % ibuf->x;
 
1477
        if (x_px<0) x_px += ibuf->x;
 
1478
        y_px = y_px % ibuf->y;
 
1479
        if (y_px<0) y_px += ibuf->y;
 
1480
        
 
1481
        if (ps->tool==PAINT_TOOL_CLONE) {
 
1482
                size = sizeof(ProjPixelClone);
 
1483
        }
 
1484
        else if (ps->tool==PAINT_TOOL_SMEAR) {
 
1485
                size = sizeof(ProjPixelClone);
 
1486
        }
 
1487
        else {
 
1488
                size = sizeof(ProjPixel);
 
1489
        }
 
1490
        
 
1491
        projPixel = (ProjPixel *)BLI_memarena_alloc(arena, size);
 
1492
        //memset(projPixel, 0, size);
 
1493
        
 
1494
        if (ibuf->rect_float) {
 
1495
                projPixel->pixel.f_pt = (float *)ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4);
 
1496
                projPixel->origColor.f[0] = projPixel->newColor.f[0] = projPixel->pixel.f_pt[0];  
 
1497
                projPixel->origColor.f[1] = projPixel->newColor.f[1] = projPixel->pixel.f_pt[1];  
 
1498
                projPixel->origColor.f[2] = projPixel->newColor.f[2] = projPixel->pixel.f_pt[2];  
 
1499
                projPixel->origColor.f[3] = projPixel->newColor.f[3] = projPixel->pixel.f_pt[3];  
 
1500
        }
 
1501
        else {
 
1502
                projPixel->pixel.ch_pt = ((unsigned char *)ibuf->rect + ((x_px + y_px * ibuf->x) * 4));
 
1503
                projPixel->origColor.uint = projPixel->newColor.uint = *projPixel->pixel.uint_pt;
 
1504
        }
 
1505
        
 
1506
        /* screenspace unclamped, we could keep its z and w values but dont need them at the moment */
 
1507
        VECCOPY2D(projPixel->projCoSS, pixelScreenCo);
 
1508
        
 
1509
        projPixel->x_px = x_px;
 
1510
        projPixel->y_px = y_px;
 
1511
        
 
1512
        projPixel->mask = (unsigned short)(mask * 65535);
 
1513
        projPixel->mask_max = 0;
 
1514
        
 
1515
        /* which bounding box cell are we in?, needed for undo */
 
1516
        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 ;
 
1517
        
 
1518
        /* done with view3d_project_float inline */
 
1519
        if (ps->tool==PAINT_TOOL_CLONE) {
 
1520
                if (ps->dm_mtface_clone) {
 
1521
                        ImBuf *ibuf_other;
 
1522
                        const MTFace *tf_other = ps->dm_mtface_clone + face_index;
 
1523
                        
 
1524
                        if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf(tf_other->tpage, NULL))) {
 
1525
                                /* BKE_image_get_ibuf - TODO - this may be slow */
 
1526
                                
 
1527
                                if (ibuf->rect_float) {
 
1528
                                        if (ibuf_other->rect_float) { /* from float to float */
 
1529
                                                project_face_pixel(tf_other, ibuf_other, w, side, NULL, ((ProjPixelClone *)projPixel)->clonepx.f);
 
1530
                                        }
 
1531
                                        else { /* from char to float */
 
1532
                                                unsigned char rgba_ub[4];
 
1533
                                                project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, NULL);
 
1534
                                                IMAPAINT_CHAR_RGBA_TO_FLOAT(((ProjPixelClone *)projPixel)->clonepx.f, rgba_ub);
 
1535
                                        }
 
1536
                                }
 
1537
                                else {
 
1538
                                        if (ibuf_other->rect_float) { /* float to char */
 
1539
                                                float rgba[4];
 
1540
                                                project_face_pixel(tf_other, ibuf_other, w, side, NULL, rgba);
 
1541
                                                IMAPAINT_FLOAT_RGBA_TO_CHAR(((ProjPixelClone *)projPixel)->clonepx.ch, rgba)
 
1542
                                        }
 
1543
                                        else { /* char to char */
 
1544
                                                project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL);
 
1545
                                        }
 
1546
                                }
 
1547
                        }
 
1548
                        else {
 
1549
                                if (ibuf->rect_float) {
 
1550
                                        ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0;
 
1551
                                }
 
1552
                                else {
 
1553
                                        ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0;
 
1554
                                }
 
1555
                        }
 
1556
                        
 
1557
                }
 
1558
                else {
 
1559
                        float co[2];
 
1560
                        Vec2Subf(co, projPixel->projCoSS, (float *)ps->cloneOffset);
 
1561
                        
 
1562
                        /* no need to initialize the bucket, we're only checking buckets faces and for this
 
1563
                         * the faces are alredy initialized in project_paint_delayed_face_init(...) */
 
1564
                        if (ibuf->rect_float) {
 
1565
                                if (!project_paint_PickColor(ps, co, ((ProjPixelClone *)projPixel)->clonepx.f, NULL, 1)) {
 
1566
                                        ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0; /* zero alpha - ignore */
 
1567
                                }
 
1568
                        }
 
1569
                        else {
 
1570
                                if (!project_paint_PickColor(ps, co, NULL, ((ProjPixelClone *)projPixel)->clonepx.ch, 1)) {
 
1571
                                        ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0; /* zero alpha - ignore */
 
1572
                                }
 
1573
                        }
 
1574
                }
 
1575
        }
 
1576
        
 
1577
#ifdef PROJ_DEBUG_PAINT
 
1578
        if (ibuf->rect_float)   projPixel->pixel.f_pt[0] = 0;
 
1579
        else                                    projPixel->pixel.ch_pt[0] = 0;
 
1580
#endif
 
1581
        projPixel->image_index = image_index;
 
1582
        
 
1583
        return projPixel;
 
1584
}
 
1585
 
 
1586
static int line_clip_rect2f(
 
1587
                rctf *rect,
 
1588
                const float l1[2], const float l2[2],
 
1589
                float l1_clip[2], float l2_clip[2])
 
1590
{
 
1591
        /* first account for horizontal, then vertical lines */
 
1592
        /* horiz */
 
1593
        if (fabsf(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) {
 
1594
                /* is the line out of range on its Y axis? */
 
1595
                if (l1[1] < rect->ymin || l1[1] > rect->ymax) {
 
1596
                        return 0;
 
1597
                }
 
1598
                /* line is out of range on its X axis */
 
1599
                if ((l1[0] < rect->xmin && l2[0] < rect->xmin) || (l1[0] > rect->xmax && l2[0] > rect->xmax)) {
 
1600
                        return 0;
 
1601
                }
 
1602
                
 
1603
                
 
1604
                if (fabsf(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a single point  (or close to)*/
 
1605
                        if (BLI_in_rctf(rect, l1[0], l1[1])) {
 
1606
                                VECCOPY2D(l1_clip, l1);
 
1607
                                VECCOPY2D(l2_clip, l2);
 
1608
                                return 1;
 
1609
                        }
 
1610
                        else {
 
1611
                                return 0;
 
1612
                        }
 
1613
                }
 
1614
                
 
1615
                VECCOPY2D(l1_clip, l1);
 
1616
                VECCOPY2D(l2_clip, l2);
 
1617
                CLAMP(l1_clip[0], rect->xmin, rect->xmax);
 
1618
                CLAMP(l2_clip[0], rect->xmin, rect->xmax);
 
1619
                return 1;
 
1620
        }
 
1621
        else if (fabsf(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) {
 
1622
                /* is the line out of range on its X axis? */
 
1623
                if (l1[0] < rect->xmin || l1[0] > rect->xmax) {
 
1624
                        return 0;
 
1625
                }
 
1626
                
 
1627
                /* line is out of range on its Y axis */
 
1628
                if ((l1[1] < rect->ymin && l2[1] < rect->ymin) || (l1[1] > rect->ymax && l2[1] > rect->ymax)) {
 
1629
                        return 0;
 
1630
                }
 
1631
                
 
1632
                if (fabsf(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a single point  (or close to)*/
 
1633
                        if (BLI_in_rctf(rect, l1[0], l1[1])) {
 
1634
                                VECCOPY2D(l1_clip, l1);
 
1635
                                VECCOPY2D(l2_clip, l2);
 
1636
                                return 1;
 
1637
                        }
 
1638
                        else {
 
1639
                                return 0;
 
1640
                        }
 
1641
                }
 
1642
                
 
1643
                VECCOPY2D(l1_clip, l1);
 
1644
                VECCOPY2D(l2_clip, l2);
 
1645
                CLAMP(l1_clip[1], rect->ymin, rect->ymax);
 
1646
                CLAMP(l2_clip[1], rect->ymin, rect->ymax);
 
1647
                return 1;
 
1648
        }
 
1649
        else {
 
1650
                float isect;
 
1651
                short ok1 = 0;
 
1652
                short ok2 = 0;
 
1653
                
 
1654
                /* Done with vertical lines */
 
1655
                
 
1656
                /* are either of the points inside the rectangle ? */
 
1657
                if (BLI_in_rctf(rect, l1[0], l1[1])) {
 
1658
                        VECCOPY2D(l1_clip, l1);
 
1659
                        ok1 = 1;
 
1660
                }
 
1661
                
 
1662
                if (BLI_in_rctf(rect, l2[0], l2[1])) {
 
1663
                        VECCOPY2D(l2_clip, l2);
 
1664
                        ok2 = 1;
 
1665
                }
 
1666
                
 
1667
                /* line inside rect */
 
1668
                if (ok1 && ok2) return 1;
 
1669
                
 
1670
                /* top/bottom */
 
1671
                if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
 
1672
                        if (l1[1] < l2[1]) { /* line 1 is outside */
 
1673
                                l1_clip[0] = isect;
 
1674
                                l1_clip[1] = rect->ymin;
 
1675
                                ok1 = 1;
 
1676
                        }
 
1677
                        else {
 
1678
                                l2_clip[0] = isect;
 
1679
                                l2_clip[1] = rect->ymin;
 
1680
                                ok2 = 2;
 
1681
                        }
 
1682
                }
 
1683
                
 
1684
                if (ok1 && ok2) return 1;
 
1685
                
 
1686
                if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
 
1687
                        if (l1[1] > l2[1]) { /* line 1 is outside */
 
1688
                                l1_clip[0] = isect;
 
1689
                                l1_clip[1] = rect->ymax;
 
1690
                                ok1 = 1;
 
1691
                        }
 
1692
                        else {
 
1693
                                l2_clip[0] = isect;
 
1694
                                l2_clip[1] = rect->ymax;
 
1695
                                ok2 = 2;
 
1696
                        }
 
1697
                }
 
1698
                
 
1699
                if (ok1 && ok2) return 1;
 
1700
                
 
1701
                /* left/right */
 
1702
                if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
 
1703
                        if (l1[0] < l2[0]) { /* line 1 is outside */
 
1704
                                l1_clip[0] = rect->xmin;
 
1705
                                l1_clip[1] = isect;
 
1706
                                ok1 = 1;
 
1707
                        }
 
1708
                        else {
 
1709
                                l2_clip[0] = rect->xmin;
 
1710
                                l2_clip[1] = isect;
 
1711
                                ok2 = 2;
 
1712
                        }
 
1713
                }
 
1714
        
 
1715
                if (ok1 && ok2) return 1;
 
1716
                
 
1717
                if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
 
1718
                        if (l1[0] > l2[0]) { /* line 1 is outside */
 
1719
                                l1_clip[0] = rect->xmax;
 
1720
                                l1_clip[1] = isect;
 
1721
                                ok1 = 1;
 
1722
                        }
 
1723
                        else {
 
1724
                                l2_clip[0] = rect->xmax;
 
1725
                                l2_clip[1] = isect;
 
1726
                                ok2 = 2;
 
1727
                        }
 
1728
                }
 
1729
                
 
1730
                if (ok1 && ok2) {
 
1731
                        return 1;
 
1732
                }
 
1733
                else {
 
1734
                        return 0;
 
1735
                }
 
1736
        }
 
1737
}
 
1738
 
 
1739
 
 
1740
 
 
1741
/* scale the quad & tri about its center
 
1742
 * scaling by PROJ_FACE_SCALE_SEAM (0.99x) is used for getting fake UV pixel coords that are on the
 
1743
 * edge of the face but slightly inside it occlusion tests dont return hits on adjacent faces */
 
1744
static void scale_quad(float insetCos[4][3], float *origCos[4], const float inset)
 
1745
{
 
1746
        float cent[3];
 
1747
        cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0] + origCos[3][0]) / 4.0f;
 
1748
        cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1] + origCos[3][1]) / 4.0f;
 
1749
        cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2] + origCos[3][2]) / 4.0f;
 
1750
        
 
1751
        VecSubf(insetCos[0], origCos[0], cent);
 
1752
        VecSubf(insetCos[1], origCos[1], cent);
 
1753
        VecSubf(insetCos[2], origCos[2], cent);
 
1754
        VecSubf(insetCos[3], origCos[3], cent);
 
1755
        
 
1756
        VecMulf(insetCos[0], inset);
 
1757
        VecMulf(insetCos[1], inset);
 
1758
        VecMulf(insetCos[2], inset);
 
1759
        VecMulf(insetCos[3], inset);
 
1760
        
 
1761
        VecAddf(insetCos[0], insetCos[0], cent);
 
1762
        VecAddf(insetCos[1], insetCos[1], cent);
 
1763
        VecAddf(insetCos[2], insetCos[2], cent);
 
1764
        VecAddf(insetCos[3], insetCos[3], cent);
 
1765
}
 
1766
 
 
1767
 
 
1768
static void scale_tri(float insetCos[4][3], float *origCos[4], const float inset)
 
1769
{
 
1770
        float cent[3];
 
1771
        cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0]) / 3.0f;
 
1772
        cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1]) / 3.0f;
 
1773
        cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2]) / 3.0f;
 
1774
        
 
1775
        VecSubf(insetCos[0], origCos[0], cent);
 
1776
        VecSubf(insetCos[1], origCos[1], cent);
 
1777
        VecSubf(insetCos[2], origCos[2], cent);
 
1778
        
 
1779
        VecMulf(insetCos[0], inset);
 
1780
        VecMulf(insetCos[1], inset);
 
1781
        VecMulf(insetCos[2], inset);
 
1782
        
 
1783
        VecAddf(insetCos[0], insetCos[0], cent);
 
1784
        VecAddf(insetCos[1], insetCos[1], cent);
 
1785
        VecAddf(insetCos[2], insetCos[2], cent);
 
1786
}
 
1787
 
 
1788
 
 
1789
static float Vec2Lenf_nosqrt(const float *v1, const float *v2)
 
1790
{
 
1791
        float x, y;
 
1792
 
 
1793
        x = v1[0]-v2[0];
 
1794
        y = v1[1]-v2[1];
 
1795
        return x*x+y*y;
 
1796
}
 
1797
 
 
1798
static float Vec2Lenf_nosqrt_other(const float *v1, const float v2_1, const float v2_2)
 
1799
{
 
1800
        float x, y;
 
1801
 
 
1802
        x = v1[0]-v2_1;
 
1803
        y = v1[1]-v2_2;
 
1804
        return x*x+y*y;
 
1805
}
 
1806
 
 
1807
/* note, use a squared value so we can use Vec2Lenf_nosqrt
 
1808
 * be sure that you have done a bounds check first or this may fail */
 
1809
/* only give bucket_bounds as an arg because we need it elsewhere */
 
1810
static int project_bucket_isect_circle(const int bucket_x, const int bucket_y, const float cent[2], const float radius_squared, rctf *bucket_bounds)
 
1811
{
 
1812
         
 
1813
        /* Would normally to a simple intersection test, however we know the bounds of these 2 alredy intersect 
 
1814
         * so we only need to test if the center is inside the vertical or horizontal bounds on either axis,
 
1815
         * this is even less work then an intersection test
 
1816
         * 
 
1817
        if (BLI_in_rctf(bucket_bounds, cent[0], cent[1]))
 
1818
                return 1;
 
1819
         */
 
1820
        
 
1821
        if((bucket_bounds->xmin <= cent[0] && bucket_bounds->xmax >= cent[0]) || (bucket_bounds->ymin <= cent[1] && bucket_bounds->ymax >= cent[1]) ) {
 
1822
           return 1;
 
1823
        }
 
1824
        
 
1825
        /* out of bounds left */
 
1826
        if (cent[0] < bucket_bounds->xmin) {
 
1827
                /* lower left out of radius test */
 
1828
                if (cent[1] < bucket_bounds->ymin) {
 
1829
                        return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmin, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
 
1830
                } 
 
1831
                /* top left test */
 
1832
                else if (cent[1] > bucket_bounds->ymax) {
 
1833
                        return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmin, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
 
1834
                }
 
1835
        }
 
1836
        else if (cent[0] > bucket_bounds->xmax) {
 
1837
                /* lower right out of radius test */
 
1838
                if (cent[1] < bucket_bounds->ymin) {
 
1839
                        return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmax, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
 
1840
                } 
 
1841
                /* top right test */
 
1842
                else if (cent[1] > bucket_bounds->ymax) {
 
1843
                        return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmax, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
 
1844
                }
 
1845
        }
 
1846
        
 
1847
        return 0;
 
1848
}
 
1849
 
 
1850
 
 
1851
 
 
1852
/* Note for rect_to_uvspace_ortho() and rect_to_uvspace_persp()
 
1853
 * in ortho view this function gives good results when bucket_bounds are outside the triangle
 
1854
 * however in some cases, perspective view will mess up with faces that have minimal screenspace area (viewed from the side)
 
1855
 * 
 
1856
 * for this reason its not relyable in this case so we'll use the Simple Barycentric' funcs that only account for points inside the triangle.
 
1857
 * however switching back to this for ortho is always an option */
 
1858
 
 
1859
static void rect_to_uvspace_ortho(
 
1860
                rctf *bucket_bounds,
 
1861
                float *v1coSS, float *v2coSS, float *v3coSS,
 
1862
                float *uv1co, float *uv2co, float *uv3co,
 
1863
                float bucket_bounds_uv[4][2],
 
1864
                const int flip)
 
1865
{
 
1866
        float uv[2];
 
1867
        float w[3];
 
1868
        
 
1869
        /* get the UV space bounding box */
 
1870
        uv[0] = bucket_bounds->xmax;
 
1871
        uv[1] = bucket_bounds->ymin;
 
1872
        BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w);
 
1873
        Vec2Weightf(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w);
 
1874
 
 
1875
        //uv[0] = bucket_bounds->xmax; // set above
 
1876
        uv[1] = bucket_bounds->ymax;
 
1877
        BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w);
 
1878
        Vec2Weightf(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w);
 
1879
 
 
1880
        uv[0] = bucket_bounds->xmin;
 
1881
        //uv[1] = bucket_bounds->ymax; // set above
 
1882
        BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w);
 
1883
        Vec2Weightf(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w);
 
1884
 
 
1885
        //uv[0] = bucket_bounds->xmin; // set above
 
1886
        uv[1] = bucket_bounds->ymin;
 
1887
        BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w);
 
1888
        Vec2Weightf(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w);
 
1889
}
 
1890
 
 
1891
/* same as above but use BarycentricWeightsPersp2f */
 
1892
static void rect_to_uvspace_persp(
 
1893
                rctf *bucket_bounds,
 
1894
                float *v1coSS, float *v2coSS, float *v3coSS,
 
1895
                float *uv1co, float *uv2co, float *uv3co,
 
1896
                float bucket_bounds_uv[4][2],
 
1897
                const int flip
 
1898
        )
 
1899
{
 
1900
        float uv[2];
 
1901
        float w[3];
 
1902
        
 
1903
        /* get the UV space bounding box */
 
1904
        uv[0] = bucket_bounds->xmax;
 
1905
        uv[1] = bucket_bounds->ymin;
 
1906
        BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w);
 
1907
        Vec2Weightf(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w);
 
1908
 
 
1909
        //uv[0] = bucket_bounds->xmax; // set above
 
1910
        uv[1] = bucket_bounds->ymax;
 
1911
        BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w);
 
1912
        Vec2Weightf(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w);
 
1913
 
 
1914
        uv[0] = bucket_bounds->xmin;
 
1915
        //uv[1] = bucket_bounds->ymax; // set above
 
1916
        BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w);
 
1917
        Vec2Weightf(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w);
 
1918
 
 
1919
        //uv[0] = bucket_bounds->xmin; // set above
 
1920
        uv[1] = bucket_bounds->ymin;
 
1921
        BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w);
 
1922
        Vec2Weightf(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w);
 
1923
}
 
1924
 
 
1925
/* This works as we need it to but we can save a few steps and not use it */
 
1926
#if 0
 
1927
static float angle_2d_clockwise(const float p1[2], const float p2[2], const float p3[2])
 
1928
{
 
1929
        float v1[2], v2[2];
 
1930
        
 
1931
        v1[0] = p1[0]-p2[0];    v1[1] = p1[1]-p2[1];
 
1932
        v2[0] = p3[0]-p2[0];    v2[1] = p3[1]-p2[1];
 
1933
        
 
1934
        return -atan2(v1[0]*v2[1] - v1[1]*v2[0], v1[0]*v2[0]+v1[1]*v2[1]);
 
1935
}
 
1936
#endif
 
1937
 
 
1938
#define ISECT_1 (1)
 
1939
#define ISECT_2 (1<<1)
 
1940
#define ISECT_3 (1<<2)
 
1941
#define ISECT_4 (1<<3)
 
1942
#define ISECT_ALL3 ((1<<3)-1)
 
1943
#define ISECT_ALL4 ((1<<4)-1)
 
1944
 
 
1945
/* limit must be a fraction over 1.0f */
 
1946
static int IsectPT2Df_limit(float pt[2], float v1[2], float v2[2], float v3[2], float limit)
 
1947
{
 
1948
        return ((AreaF2Dfl(pt,v1,v2) + AreaF2Dfl(pt,v2,v3) + AreaF2Dfl(pt,v3,v1)) / (AreaF2Dfl(v1,v2,v3))) < limit;
 
1949
}
 
1950
 
 
1951
/* Clip the face by a bucket and set the uv-space bucket_bounds_uv
 
1952
 * so we have the clipped UV's to do pixel intersection tests with 
 
1953
 * */
 
1954
static int float_z_sort_flip(const void *p1, const void *p2) {
 
1955
        return (((float *)p1)[2] < ((float *)p2)[2] ? 1:-1);
 
1956
}
 
1957
 
 
1958
static int float_z_sort(const void *p1, const void *p2) {
 
1959
        return (((float *)p1)[2] < ((float *)p2)[2] ?-1:1);
 
1960
}
 
1961
 
 
1962
static void project_bucket_clip_face(
 
1963
                const int is_ortho,
 
1964
                rctf *bucket_bounds,
 
1965
                float *v1coSS, float *v2coSS, float *v3coSS,
 
1966
                float *uv1co, float *uv2co, float *uv3co,
 
1967
                float bucket_bounds_uv[8][2],
 
1968
                int *tot)
 
1969
{
 
1970
        int inside_bucket_flag = 0;
 
1971
        int inside_face_flag = 0;
 
1972
        const int flip = ((SIDE_OF_LINE(v1coSS, v2coSS, v3coSS) > 0.0f) != (SIDE_OF_LINE(uv1co, uv2co, uv3co) > 0.0f));
 
1973
        
 
1974
        float bucket_bounds_ss[4][2];
 
1975
 
 
1976
        /* get the UV space bounding box */
 
1977
        inside_bucket_flag |= BLI_in_rctf(bucket_bounds, v1coSS[0], v1coSS[1]);
 
1978
        inside_bucket_flag |= BLI_in_rctf(bucket_bounds, v2coSS[0], v2coSS[1])          << 1;
 
1979
        inside_bucket_flag |= BLI_in_rctf(bucket_bounds, v3coSS[0], v3coSS[1])          << 2;
 
1980
        
 
1981
        if (inside_bucket_flag == ISECT_ALL3) {
 
1982
                /* all screenspace points are inside the bucket bounding box, this means we dont need to clip and can simply return the UVs */
 
1983
                if (flip) { /* facing the back? */
 
1984
                        VECCOPY2D(bucket_bounds_uv[0], uv3co);
 
1985
                        VECCOPY2D(bucket_bounds_uv[1], uv2co);
 
1986
                        VECCOPY2D(bucket_bounds_uv[2], uv1co);
 
1987
                }
 
1988
                else {
 
1989
                        VECCOPY2D(bucket_bounds_uv[0], uv1co);
 
1990
                        VECCOPY2D(bucket_bounds_uv[1], uv2co);
 
1991
                        VECCOPY2D(bucket_bounds_uv[2], uv3co);
 
1992
                }
 
1993
                
 
1994
                *tot = 3; 
 
1995
                return;
 
1996
        }
 
1997
        
 
1998
        /* get the UV space bounding box */
 
1999
        /* use IsectPT2Df_limit here so we catch points are are touching the tri edge (or a small fraction over) */
 
2000
        bucket_bounds_ss[0][0] = bucket_bounds->xmax;
 
2001
        bucket_bounds_ss[0][1] = bucket_bounds->ymin;
 
2002
        inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[0], v1coSS, v2coSS, v3coSS, 1+PROJ_GEOM_TOLERANCE) ? ISECT_1 : 0);
 
2003
        
 
2004
        bucket_bounds_ss[1][0] = bucket_bounds->xmax;
 
2005
        bucket_bounds_ss[1][1] = bucket_bounds->ymax;
 
2006
        inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[1], v1coSS, v2coSS, v3coSS, 1+PROJ_GEOM_TOLERANCE) ? ISECT_2 : 0);
 
2007
 
 
2008
        bucket_bounds_ss[2][0] = bucket_bounds->xmin;
 
2009
        bucket_bounds_ss[2][1] = bucket_bounds->ymax;
 
2010
        inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[2], v1coSS, v2coSS, v3coSS, 1+PROJ_GEOM_TOLERANCE) ? ISECT_3 : 0);
 
2011
 
 
2012
        bucket_bounds_ss[3][0] = bucket_bounds->xmin;
 
2013
        bucket_bounds_ss[3][1] = bucket_bounds->ymin;
 
2014
        inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[3], v1coSS, v2coSS, v3coSS, 1+PROJ_GEOM_TOLERANCE) ? ISECT_4 : 0);
 
2015
        
 
2016
        if (inside_face_flag == ISECT_ALL4) {
 
2017
                /* bucket is totally inside the screenspace face, we can safely use weights */
 
2018
                
 
2019
                if (is_ortho)   rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
 
2020
                else                    rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
 
2021
                
 
2022
                *tot = 4;
 
2023
                return;
 
2024
        }
 
2025
        else {
 
2026
                /* The Complicated Case! 
 
2027
                 * 
 
2028
                 * The 2 cases above are where the face is inside the bucket or the bucket is inside the face.
 
2029
                 * 
 
2030
                 * we need to make a convex polyline from the intersection between the screenspace face
 
2031
                 * and the bucket bounds.
 
2032
                 * 
 
2033
                 * There are a number of ways this could be done, currently it just collects all intersecting verts,
 
2034
                 * and line intersections,  then sorts them clockwise, this is a lot easier then evaluating the geometry to
 
2035
                 * do a correct clipping on both shapes. */
 
2036
                
 
2037
                
 
2038
                /* add a bunch of points, we know must make up the convex hull which is the clipped rect and triangle */
 
2039
                
 
2040
                
 
2041
                
 
2042
                /* Maximum possible 6 intersections when using a rectangle and triangle */
 
2043
                float isectVCosSS[8][3]; /* The 3rd float is used to store angle for qsort(), NOT as a Z location */
 
2044
                float v1_clipSS[2], v2_clipSS[2];
 
2045
                float w[3];
 
2046
                
 
2047
                /* calc center*/
 
2048
                float cent[2] = {0.0f, 0.0f};
 
2049
                /*float up[2] = {0.0f, 1.0f};*/
 
2050
                int i;
 
2051
                short doubles;
 
2052
                
 
2053
                (*tot) = 0;
 
2054
                
 
2055
                if (inside_face_flag & ISECT_1) { VECCOPY2D(isectVCosSS[*tot], bucket_bounds_ss[0]); (*tot)++; }
 
2056
                if (inside_face_flag & ISECT_2) { VECCOPY2D(isectVCosSS[*tot], bucket_bounds_ss[1]); (*tot)++; }
 
2057
                if (inside_face_flag & ISECT_3) { VECCOPY2D(isectVCosSS[*tot], bucket_bounds_ss[2]); (*tot)++; }
 
2058
                if (inside_face_flag & ISECT_4) { VECCOPY2D(isectVCosSS[*tot], bucket_bounds_ss[3]); (*tot)++; }
 
2059
                
 
2060
                if (inside_bucket_flag & ISECT_1) {     VECCOPY2D(isectVCosSS[*tot], v1coSS); (*tot)++; }
 
2061
                if (inside_bucket_flag & ISECT_2) {     VECCOPY2D(isectVCosSS[*tot], v2coSS); (*tot)++; }
 
2062
                if (inside_bucket_flag & ISECT_3) {     VECCOPY2D(isectVCosSS[*tot], v3coSS); (*tot)++; }
 
2063
                
 
2064
                if ((inside_bucket_flag & (ISECT_1|ISECT_2)) != (ISECT_1|ISECT_2)) {
 
2065
                        if (line_clip_rect2f(bucket_bounds, v1coSS, v2coSS, v1_clipSS, v2_clipSS)) {
 
2066
                                if ((inside_bucket_flag & ISECT_1)==0) { VECCOPY2D(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
 
2067
                                if ((inside_bucket_flag & ISECT_2)==0) { VECCOPY2D(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
 
2068
                        }
 
2069
                }
 
2070
                
 
2071
                if ((inside_bucket_flag & (ISECT_2|ISECT_3)) != (ISECT_2|ISECT_3)) {
 
2072
                        if (line_clip_rect2f(bucket_bounds, v2coSS, v3coSS, v1_clipSS, v2_clipSS)) {
 
2073
                                if ((inside_bucket_flag & ISECT_2)==0) { VECCOPY2D(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
 
2074
                                if ((inside_bucket_flag & ISECT_3)==0) { VECCOPY2D(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
 
2075
                        }
 
2076
                }       
 
2077
                
 
2078
                if ((inside_bucket_flag & (ISECT_3|ISECT_1)) != (ISECT_3|ISECT_1)) {
 
2079
                        if (line_clip_rect2f(bucket_bounds, v3coSS, v1coSS, v1_clipSS, v2_clipSS)) {
 
2080
                                if ((inside_bucket_flag & ISECT_3)==0) { VECCOPY2D(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
 
2081
                                if ((inside_bucket_flag & ISECT_1)==0) { VECCOPY2D(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
 
2082
                        }
 
2083
                }
 
2084
                
 
2085
                
 
2086
                if ((*tot) < 3) { /* no intersections to speak of */
 
2087
                        *tot = 0;
 
2088
                        return;
 
2089
                }
 
2090
        
 
2091
                /* now we have all points we need, collect their angles and sort them clockwise */
 
2092
                
 
2093
                for(i=0; i<(*tot); i++) {
 
2094
                        cent[0] += isectVCosSS[i][0];
 
2095
                        cent[1] += isectVCosSS[i][1];
 
2096
                }
 
2097
                cent[0] = cent[0] / (float)(*tot);
 
2098
                cent[1] = cent[1] / (float)(*tot);
 
2099
                
 
2100
                
 
2101
                
 
2102
                /* Collect angles for every point around the center point */
 
2103
 
 
2104
                
 
2105
#if 0   /* uses a few more cycles then the above loop */
 
2106
                for(i=0; i<(*tot); i++) {
 
2107
                        isectVCosSS[i][2] = angle_2d_clockwise(up, cent, isectVCosSS[i]);
 
2108
                }
 
2109
#endif
 
2110
 
 
2111
                v1_clipSS[0] = cent[0]; /* Abuse this var for the loop below */
 
2112
                v1_clipSS[1] = cent[1] + 1.0f;
 
2113
                
 
2114
                for(i=0; i<(*tot); i++) {
 
2115
                        v2_clipSS[0] = isectVCosSS[i][0] - cent[0];
 
2116
                        v2_clipSS[1] = isectVCosSS[i][1] - cent[1];
 
2117
                        isectVCosSS[i][2] = atan2f(v1_clipSS[0]*v2_clipSS[1] - v1_clipSS[1]*v2_clipSS[0], v1_clipSS[0]*v2_clipSS[0]+v1_clipSS[1]*v2_clipSS[1]); 
 
2118
                }
 
2119
                
 
2120
                if (flip)       qsort(isectVCosSS, *tot, sizeof(float)*3, float_z_sort_flip);
 
2121
                else            qsort(isectVCosSS, *tot, sizeof(float)*3, float_z_sort);
 
2122
                
 
2123
                /* remove doubles */
 
2124
                /* first/last check */
 
2125
                if (fabsf(isectVCosSS[0][0]-isectVCosSS[(*tot)-1][0]) < PROJ_GEOM_TOLERANCE &&  fabsf(isectVCosSS[0][1]-isectVCosSS[(*tot)-1][1]) < PROJ_GEOM_TOLERANCE) {
 
2126
                        (*tot)--;
 
2127
                }
 
2128
                
 
2129
                /* its possible there is only a few left after remove doubles */
 
2130
                if ((*tot) < 3) {
 
2131
                        // printf("removed too many doubles A\n");
 
2132
                        *tot = 0;
 
2133
                        return;
 
2134
                }
 
2135
                
 
2136
                doubles = TRUE;
 
2137
                while (doubles==TRUE) {
 
2138
                        doubles = FALSE;
 
2139
                        for(i=1; i<(*tot); i++) {
 
2140
                                if (fabsf(isectVCosSS[i-1][0]-isectVCosSS[i][0]) < PROJ_GEOM_TOLERANCE &&
 
2141
                                        fabsf(isectVCosSS[i-1][1]-isectVCosSS[i][1]) < PROJ_GEOM_TOLERANCE)
 
2142
                                {
 
2143
                                        int j;
 
2144
                                        for(j=i+1; j<(*tot); j++) {
 
2145
                                                isectVCosSS[j-1][0] = isectVCosSS[j][0]; 
 
2146
                                                isectVCosSS[j-1][1] = isectVCosSS[j][1]; 
 
2147
                                        }
 
2148
                                        doubles = TRUE; /* keep looking for more doubles */
 
2149
                                        (*tot)--;
 
2150
                                }
 
2151
                        }
 
2152
                }
 
2153
                
 
2154
                /* its possible there is only a few left after remove doubles */
 
2155
                if ((*tot) < 3) {
 
2156
                        // printf("removed too many doubles B\n");
 
2157
                        *tot = 0;
 
2158
                        return;
 
2159
                }
 
2160
                
 
2161
                
 
2162
                if (is_ortho) {
 
2163
                        for(i=0; i<(*tot); i++) {
 
2164
                                BarycentricWeights2f(isectVCosSS[i], v1coSS, v2coSS, v3coSS, w);
 
2165
                                Vec2Weightf(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
 
2166
                        }
 
2167
                }
 
2168
                else {
 
2169
                        for(i=0; i<(*tot); i++) {
 
2170
                                BarycentricWeightsPersp2f(isectVCosSS[i], v1coSS, v2coSS, v3coSS, w);
 
2171
                                Vec2Weightf(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
 
2172
                        }
 
2173
                }
 
2174
        }
 
2175
 
 
2176
#ifdef PROJ_DEBUG_PRINT_CLIP
 
2177
        /* include this at the bottom of the above function to debug the output */
 
2178
 
 
2179
        {
 
2180
                /* If there are ever any problems, */
 
2181
                float test_uv[4][2];
 
2182
                int i;
 
2183
                if (is_ortho)   rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
 
2184
                else                            rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
 
2185
                printf("(  [(%f,%f), (%f,%f), (%f,%f), (%f,%f)], ", test_uv[0][0], test_uv[0][1],   test_uv[1][0], test_uv[1][1],    test_uv[2][0], test_uv[2][1],    test_uv[3][0], test_uv[3][1]);
 
2186
                
 
2187
                printf("  [(%f,%f), (%f,%f), (%f,%f)], ", uv1co[0], uv1co[1],   uv2co[0], uv2co[1],    uv3co[0], uv3co[1]);
 
2188
                
 
2189
                printf("[");
 
2190
                for (i=0; i < (*tot); i++) {
 
2191
                        printf("(%f, %f),", bucket_bounds_uv[i][0], bucket_bounds_uv[i][1]);
 
2192
                }
 
2193
                printf("]),\\\n");
 
2194
        }
 
2195
#endif
 
2196
}
 
2197
 
 
2198
        /*
 
2199
# This script creates faces in a blender scene from printed data above.
 
2200
 
 
2201
project_ls = [
 
2202
...(output from above block)...
 
2203
]
 
2204
 
 
2205
from Blender import Scene, Mesh, Window, sys, Mathutils
 
2206
 
 
2207
import bpy
 
2208
 
 
2209
V = Mathutils.Vector
 
2210
 
 
2211
def main():
 
2212
        sce = bpy.data.scenes.active
 
2213
        
 
2214
        for item in project_ls:
 
2215
                bb = item[0]
 
2216
                uv = item[1]
 
2217
                poly = item[2]
 
2218
                
 
2219
                me = bpy.data.meshes.new()
 
2220
                ob = sce.objects.new(me)
 
2221
                
 
2222
                me.verts.extend([V(bb[0]).resize3D(), V(bb[1]).resize3D(), V(bb[2]).resize3D(), V(bb[3]).resize3D()])
 
2223
                me.faces.extend([(0,1,2,3),])
 
2224
                me.verts.extend([V(uv[0]).resize3D(), V(uv[1]).resize3D(), V(uv[2]).resize3D()])
 
2225
                me.faces.extend([(4,5,6),])
 
2226
                
 
2227
                vs = [V(p).resize3D() for p in poly]
 
2228
                print len(vs)
 
2229
                l = len(me.verts)
 
2230
                me.verts.extend(vs)
 
2231
                
 
2232
                i = l
 
2233
                while i < len(me.verts):
 
2234
                        ii = i+1
 
2235
                        if ii==len(me.verts):
 
2236
                                ii = l
 
2237
                        me.edges.extend([i, ii])
 
2238
                        i+=1
 
2239
 
 
2240
if __name__ == '__main__':
 
2241
        main()
 
2242
 */     
 
2243
 
 
2244
 
 
2245
#undef ISECT_1
 
2246
#undef ISECT_2
 
2247
#undef ISECT_3
 
2248
#undef ISECT_4
 
2249
#undef ISECT_ALL3
 
2250
#undef ISECT_ALL4
 
2251
 
 
2252
        
 
2253
/* checks if pt is inside a convex 2D polyline, the polyline must be ordered rotating clockwise
 
2254
 * otherwise it would have to test for mixed (SIDE_OF_LINE > 0.0f) cases */
 
2255
int IsectPoly2Df(const float pt[2], float uv[][2], const int tot)
 
2256
{
 
2257
        int i;
 
2258
        if (SIDE_OF_LINE(uv[tot-1], uv[0], pt) < 0.0f)
 
2259
                return 0;
 
2260
        
 
2261
        for (i=1; i<tot; i++) {
 
2262
                if (SIDE_OF_LINE(uv[i-1], uv[i], pt) < 0.0f)
 
2263
                        return 0;
 
2264
                
 
2265
        }
 
2266
        
 
2267
        return 1;
 
2268
}
 
2269
static int IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot)
 
2270
{
 
2271
        int i;
 
2272
        int side = (SIDE_OF_LINE(uv[tot-1], uv[0], pt) > 0.0f);
 
2273
        
 
2274
        for (i=1; i<tot; i++) {
 
2275
                if ((SIDE_OF_LINE(uv[i-1], uv[i], pt) > 0.0f) != side)
 
2276
                        return 0;
 
2277
                
 
2278
        }
 
2279
        
 
2280
        return 1;
 
2281
}
 
2282
 
 
2283
/* One of the most important function for projectiopn painting, since it selects the pixels to be added into each bucket.
 
2284
 * initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */
 
2285
static void project_paint_face_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, const int face_index, const int image_index, rctf *bucket_bounds, const ImBuf *ibuf)
 
2286
{
 
2287
        /* Projection vars, to get the 3D locations into screen space  */
 
2288
        MemArena *arena = ps->arena_mt[thread_index];
 
2289
        LinkNode **bucketPixelNodes = ps->bucketRect + bucket_index;
 
2290
        LinkNode *bucketFaceNodes = ps->bucketFaces[bucket_index];
 
2291
        
 
2292
        const MFace *mf = ps->dm_mface + face_index;
 
2293
        const MTFace *tf = ps->dm_mtface + face_index;
 
2294
        
 
2295
        /* UV/pixel seeking data */
 
2296
        int x; /* Image X-Pixel */
 
2297
        int y;/* Image Y-Pixel */
 
2298
        float mask;
 
2299
        float uv[2]; /* Image floating point UV - same as x, y but from 0.0-1.0 */
 
2300
        
 
2301
        int side;
 
2302
        float *v1coSS, *v2coSS, *v3coSS; /* vert co screen-space, these will be assigned to mf->v1,2,3 or mf->v1,3,4 */
 
2303
        
 
2304
        float *vCo[4]; /* vertex screenspace coords */
 
2305
        
 
2306
        float w[3], wco[3];
 
2307
        
 
2308
        float *uv1co, *uv2co, *uv3co; /* for convenience only, these will be assigned to tf->uv[0],1,2 or tf->uv[0],2,3 */
 
2309
        float pixelScreenCo[4];
 
2310
        
 
2311
        rcti bounds_px; /* ispace bounds */
 
2312
        /* vars for getting uvspace bounds */
 
2313
        
 
2314
        float tf_uv_pxoffset[4][2]; /* bucket bounds in UV space so we can init pixels only for this face,  */
 
2315
        float xhalfpx, yhalfpx;
 
2316
        const float ibuf_xf = ibuf->x, ibuf_yf = ibuf->y;
 
2317
        
 
2318
        int has_x_isect = 0, has_isect = 0; /* for early loop exit */
 
2319
        
 
2320
        int i1, i2, i3;
 
2321
        
 
2322
        float uv_clip[8][2];
 
2323
        int uv_clip_tot;
 
2324
        const short is_ortho = ps->is_ortho;
 
2325
        const short do_backfacecull = ps->do_backfacecull;
 
2326
        
 
2327
        vCo[0] = ps->dm_mvert[mf->v1].co;
 
2328
        vCo[1] = ps->dm_mvert[mf->v2].co;
 
2329
        vCo[2] = ps->dm_mvert[mf->v3].co;
 
2330
        
 
2331
        
 
2332
        /* Use tf_uv_pxoffset instead of tf->uv so we can offset the UV half a pixel
 
2333
         * this is done so we can avoid offseting all the pixels by 0.5 which causes
 
2334
         * problems when wrapping negative coords */
 
2335
        xhalfpx = (0.5f+   (PROJ_GEOM_TOLERANCE/3.0f)   ) / ibuf_xf;
 
2336
        yhalfpx = (0.5f+   (PROJ_GEOM_TOLERANCE/4.0f)   ) / ibuf_yf;
 
2337
        
 
2338
        /* Note about (PROJ_GEOM_TOLERANCE/x) above...
 
2339
          Needed to add this offset since UV coords are often quads aligned to pixels.
 
2340
          In this case pixels can be exactly between 2 triangles causing nasty
 
2341
          artifacts.
 
2342
          
 
2343
          This workaround can be removed and painting will still work on most cases
 
2344
          but since the first thing most people try is painting onto a quad- better make it work.
 
2345
         */
 
2346
 
 
2347
 
 
2348
 
 
2349
        tf_uv_pxoffset[0][0] = tf->uv[0][0] - xhalfpx;
 
2350
        tf_uv_pxoffset[0][1] = tf->uv[0][1] - yhalfpx;
 
2351
 
 
2352
        tf_uv_pxoffset[1][0] = tf->uv[1][0] - xhalfpx;
 
2353
        tf_uv_pxoffset[1][1] = tf->uv[1][1] - yhalfpx;
 
2354
        
 
2355
        tf_uv_pxoffset[2][0] = tf->uv[2][0] - xhalfpx;
 
2356
        tf_uv_pxoffset[2][1] = tf->uv[2][1] - yhalfpx;  
 
2357
        
 
2358
        if (mf->v4) {
 
2359
                vCo[3] = ps->dm_mvert[ mf->v4 ].co;
 
2360
                
 
2361
                tf_uv_pxoffset[3][0] = tf->uv[3][0] - xhalfpx;
 
2362
                tf_uv_pxoffset[3][1] = tf->uv[3][1] - yhalfpx;
 
2363
                side = 1;
 
2364
        }
 
2365
        else {
 
2366
                side = 0;
 
2367
        }
 
2368
        
 
2369
        do {
 
2370
                if (side==1) {
 
2371
                        i1=0; i2=2; i3=3;
 
2372
                }
 
2373
                else {
 
2374
                        i1=0; i2=1; i3=2;
 
2375
                }
 
2376
                
 
2377
                uv1co = tf_uv_pxoffset[i1]; // was tf->uv[i1];
 
2378
                uv2co = tf_uv_pxoffset[i2]; // was tf->uv[i2];
 
2379
                uv3co = tf_uv_pxoffset[i3]; // was tf->uv[i3];
 
2380
 
 
2381
                v1coSS = ps->screenCoords[ (*(&mf->v1 + i1)) ];
 
2382
                v2coSS = ps->screenCoords[ (*(&mf->v1 + i2)) ];
 
2383
                v3coSS = ps->screenCoords[ (*(&mf->v1 + i3)) ];
 
2384
                
 
2385
                /* This funtion gives is a concave polyline in UV space from the clipped quad and tri*/
 
2386
                project_bucket_clip_face(
 
2387
                                is_ortho, bucket_bounds,
 
2388
                                v1coSS, v2coSS, v3coSS,
 
2389
                                uv1co, uv2co, uv3co,
 
2390
                                uv_clip, &uv_clip_tot
 
2391
                );
 
2392
 
 
2393
                /* sometimes this happens, better just allow for 8 intersectiosn even though there should be max 6 */
 
2394
                /*
 
2395
                if (uv_clip_tot>6) {
 
2396
                        printf("this should never happen! %d\n", uv_clip_tot);
 
2397
                }*/
 
2398
                
 
2399
 
 
2400
                if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) {
 
2401
                        
 
2402
                        /* clip face and */
 
2403
                        
 
2404
                        has_isect = 0;
 
2405
                        for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
 
2406
                                //uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
 
2407
                                uv[1] = (float)y / ibuf_yf; /* use pixel offset UV coords instead */
 
2408
                                
 
2409
                                has_x_isect = 0;
 
2410
                                for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
 
2411
                                        //uv[0] = (((float)x) + 0.5f) / ibuf->x;
 
2412
                                        uv[0] = (float)x / ibuf_xf; /* use pixel offset UV coords instead */
 
2413
                                        
 
2414
                                        /* Note about IsectPoly2Df_twoside, checking the face or uv flipping doesnt work,
 
2415
                                         * could check the poly direction but better to do this */
 
2416
                                        if(     (do_backfacecull                && IsectPoly2Df(uv, uv_clip, uv_clip_tot)) ||
 
2417
                                                (do_backfacecull==0             && IsectPoly2Df_twoside(uv, uv_clip, uv_clip_tot))) {
 
2418
                                                
 
2419
                                                has_x_isect = has_isect = 1;
 
2420
                                                
 
2421
                                                if (is_ortho)   screen_px_from_ortho(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
 
2422
                                                else                    screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
 
2423
                                                
 
2424
                                                /* a pitty we need to get the worldspace pixel location here */
 
2425
                                                if(G.vd->flag & V3D_CLIPPING) {
 
2426
                                                        VecWeightf(wco, ps->dm_mvert[ (*(&mf->v1 + i1)) ].co, ps->dm_mvert[ (*(&mf->v1 + i2)) ].co, ps->dm_mvert[ (*(&mf->v1 + i3)) ].co, w);
 
2427
                                                        Mat4MulVecfl(ps->ob->obmat, wco);
 
2428
                                                        if(view3d_test_clipping(G.vd, wco)) {
 
2429
                                                                continue; /* Watch out that no code below this needs to run */
 
2430
                                                        }
 
2431
                                                }
 
2432
                                                
 
2433
                                                /* Is this UV visible from the view? - raytrace */
 
2434
                                                /* project_paint_PickFace is less complex, use for testing */
 
2435
                                                //if (project_paint_PickFace(ps, pixelScreenCo, w, &side) == face_index) {
 
2436
                                                if (ps->do_occlude==0 || !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo)) {
 
2437
                                                        
 
2438
                                                        mask = project_paint_uvpixel_mask(ps, face_index, side, w);
 
2439
                                                        
 
2440
                                                        if (mask > 0.0f) {
 
2441
                                                                BLI_linklist_prepend_arena(
 
2442
                                                                        bucketPixelNodes,
 
2443
                                                                        project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, side, w),
 
2444
                                                                        arena
 
2445
                                                                );
 
2446
                                                        }
 
2447
                                                }
 
2448
                                                
 
2449
                                        }
 
2450
//#if 0
 
2451
                                        else if (has_x_isect) {
 
2452
                                                /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
 
2453
                                                break;
 
2454
                                        }
 
2455
//#endif
 
2456
                                }
 
2457
                                
 
2458
                                
 
2459
#if 0                   /* TODO - investigate why this dosnt work sometimes! it should! */
 
2460
                                /* no intersection for this entire row, after some intersection above means we can quit now */
 
2461
                                if (has_x_isect==0 && has_isect) { 
 
2462
                                        break;
 
2463
                                }
 
2464
#endif
 
2465
                        }
 
2466
                }
 
2467
        } while(side--);
 
2468
 
 
2469
        
 
2470
        
 
2471
#ifndef PROJ_DEBUG_NOSEAMBLEED
 
2472
        if (ps->seam_bleed_px > 0.0f) {
 
2473
                int face_seam_flag;
 
2474
                
 
2475
                if (ps->thread_tot > 1)
 
2476
                        BLI_lock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
 
2477
                
 
2478
                face_seam_flag = ps->faceSeamFlags[face_index];
 
2479
                
 
2480
                /* are any of our edges un-initialized? */
 
2481
                if ((face_seam_flag & (PROJ_FACE_SEAM1|PROJ_FACE_NOSEAM1))==0 || 
 
2482
                        (face_seam_flag & (PROJ_FACE_SEAM2|PROJ_FACE_NOSEAM2))==0 || 
 
2483
                        (face_seam_flag & (PROJ_FACE_SEAM3|PROJ_FACE_NOSEAM3))==0 || 
 
2484
                        (face_seam_flag & (PROJ_FACE_SEAM4|PROJ_FACE_NOSEAM4))==0
 
2485
                ) {
 
2486
                        project_face_seams_init(ps, face_index, mf->v4);
 
2487
                        face_seam_flag = ps->faceSeamFlags[face_index];
 
2488
                        //printf("seams - %d %d %d %d\n", flag&PROJ_FACE_SEAM1, flag&PROJ_FACE_SEAM2, flag&PROJ_FACE_SEAM3, flag&PROJ_FACE_SEAM4);
 
2489
                }
 
2490
                
 
2491
                if ((face_seam_flag & (PROJ_FACE_SEAM1|PROJ_FACE_SEAM2|PROJ_FACE_SEAM3|PROJ_FACE_SEAM4))==0) {
 
2492
                        
 
2493
                        if (ps->thread_tot > 1)
 
2494
                                BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
 
2495
                        
 
2496
                }
 
2497
                else {
 
2498
                        /* we have a seam - deal with it! */
 
2499
                        
 
2500
                        /* Now create new UV's for the seam face */
 
2501
                        float (*outset_uv)[2] = ps->faceSeamUVs[face_index];
 
2502
                        float insetCos[4][3]; /* inset face coords.  NOTE!!! ScreenSace for ortho, Worldspace in prespective view */
 
2503
 
 
2504
                        float fac;
 
2505
                        float *vCoSS[4]; /* vertex screenspace coords */
 
2506
                        
 
2507
                        float bucket_clip_edges[2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */
 
2508
                        float edge_verts_inset_clip[2][3];
 
2509
                        int fidx1, fidx2; /* face edge pairs - loop throuh these ((0,1), (1,2), (2,3), (3,0)) or ((0,1), (1,2), (2,0)) for a tri */
 
2510
                        
 
2511
                        float seam_subsection[4][2];
 
2512
                        float fac1, fac2, ftot;
 
2513
                        
 
2514
                        
 
2515
                        if (outset_uv[0][0]==MAXFLOAT) /* first time initialize */
 
2516
                                uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4);
 
2517
                        
 
2518
                        /* ps->faceSeamUVs cant be modified when threading, now this is done we can unlock */
 
2519
                        if (ps->thread_tot > 1)
 
2520
                                BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
 
2521
                        
 
2522
                        vCoSS[0] = ps->screenCoords[mf->v1];
 
2523
                        vCoSS[1] = ps->screenCoords[mf->v2];
 
2524
                        vCoSS[2] = ps->screenCoords[mf->v3];
 
2525
                        if (mf->v4)
 
2526
                                vCoSS[3] = ps->screenCoords[ mf->v4 ];
 
2527
                        
 
2528
                        /* PROJ_FACE_SCALE_SEAM must be slightly less then 1.0f */
 
2529
                        if (is_ortho) {
 
2530
                                if (mf->v4)     scale_quad(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
 
2531
                                else            scale_tri(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
 
2532
                        }
 
2533
                        else {
 
2534
                                if (mf->v4)     scale_quad(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
 
2535
                                else            scale_tri(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
 
2536
                        }
 
2537
                        
 
2538
                        side = 0; /* for triangles this wont need to change */
 
2539
                        
 
2540
                        for (fidx1 = 0; fidx1 < (mf->v4 ? 4 : 3); fidx1++) {
 
2541
                                if (mf->v4)             fidx2 = (fidx1==3) ? 0 : fidx1+1; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) */
 
2542
                                else                    fidx2 = (fidx1==2) ? 0 : fidx1+1; /* next fidx in the face (0,1,2) -> (1,2,0) */
 
2543
                                
 
2544
                                if (    (face_seam_flag & (1<<fidx1)) && /* 1<<fidx1 -> PROJ_FACE_SEAM# */
 
2545
                                                line_clip_rect2f(bucket_bounds, vCoSS[fidx1], vCoSS[fidx2], bucket_clip_edges[0], bucket_clip_edges[1])
 
2546
                                ) {
 
2547
 
 
2548
                                        ftot = Vec2Lenf(vCoSS[fidx1], vCoSS[fidx2]); /* screenspace edge length */
 
2549
                                        
 
2550
                                        if (ftot > 0.0f) { /* avoid div by zero */
 
2551
                                                if (mf->v4) {
 
2552
                                                        if (fidx1==2 || fidx2==2)       side= 1;
 
2553
                                                        else                                            side= 0;
 
2554
                                                }
 
2555
                                                
 
2556
                                                fac1 = Vec2Lenf(vCoSS[fidx1], bucket_clip_edges[0]) / ftot;
 
2557
                                                fac2 = Vec2Lenf(vCoSS[fidx1], bucket_clip_edges[1]) / ftot;
 
2558
                                                
 
2559
                                                Vec2Lerpf(seam_subsection[0], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac1);
 
2560
                                                Vec2Lerpf(seam_subsection[1], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac2);
 
2561
 
 
2562
                                                Vec2Lerpf(seam_subsection[2], outset_uv[fidx1], outset_uv[fidx2], fac2);
 
2563
                                                Vec2Lerpf(seam_subsection[3], outset_uv[fidx1], outset_uv[fidx2], fac1);
 
2564
                                                
 
2565
                                                /* if the bucket_clip_edges values Z values was kept we could avoid this
 
2566
                                                 * Inset needs to be added so occlusion tests wont hit adjacent faces */
 
2567
                                                VecLerpf(edge_verts_inset_clip[0], insetCos[fidx1], insetCos[fidx2], fac1);
 
2568
                                                VecLerpf(edge_verts_inset_clip[1], insetCos[fidx1], insetCos[fidx2], fac2);
 
2569
                                                
 
2570
 
 
2571
                                                if (pixel_bounds_uv(seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3], &bounds_px, ibuf->x, ibuf->y, 1)) {
 
2572
                                                        /* bounds between the seam rect and the uvspace bucket pixels */
 
2573
                                                        
 
2574
                                                        has_isect = 0;
 
2575
                                                        for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
 
2576
                                                                // uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
 
2577
                                                                uv[1] = (float)y / ibuf_yf; /* use offset uvs instead */
 
2578
                                                                
 
2579
                                                                has_x_isect = 0;
 
2580
                                                                for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
 
2581
                                                                        //uv[0] = (((float)x) + 0.5f) / (float)ibuf->x;
 
2582
                                                                        uv[0] = (float)x / ibuf_xf; /* use offset uvs instead */
 
2583
                                                                        
 
2584
                                                                        /* test we're inside uvspace bucket and triangle bounds */
 
2585
                                                                        if (IsectPQ2Df(uv, seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3])) {
 
2586
                                                                                
 
2587
                                                                                /* We need to find the closest point along the face edge,
 
2588
                                                                                 * getting the screen_px_from_*** wont work because our actual location
 
2589
                                                                                 * is not relevent, since we are outside the face, Use VecLerpf to find
 
2590
                                                                                 * our location on the side of the face's UV */
 
2591
                                                                                /*
 
2592
                                                                                if (is_ortho)   screen_px_from_ortho(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
 
2593
                                                                                else                                    screen_px_from_persp(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
 
2594
                                                                                */
 
2595
                                                                                
 
2596
                                                                                /* Since this is a seam we need to work out where on the line this pixel is */
 
2597
                                                                                //fac = lambda_cp_line2(uv, uv_seam_quad[0], uv_seam_quad[1]);
 
2598
                                                                                
 
2599
                                                                                fac = lambda_cp_line2(uv, seam_subsection[0], seam_subsection[1]);
 
2600
                                                                                if (fac < 0.0f)         { VECCOPY(pixelScreenCo, edge_verts_inset_clip[0]); }
 
2601
                                                                                else if (fac > 1.0f)    { VECCOPY(pixelScreenCo, edge_verts_inset_clip[1]); }
 
2602
                                                                                else                            { VecLerpf(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac); }
 
2603
                                                                                
 
2604
                                                                                if (!is_ortho) {
 
2605
                                                                                        pixelScreenCo[3] = 1.0f;
 
2606
                                                                                        Mat4MulVec4fl((float (*)[4])*ps->projectMat, pixelScreenCo);
 
2607
                                                                                        pixelScreenCo[0] = (float)(curarea->winx/2.0f)+(curarea->winx/2.0f)*pixelScreenCo[0]/pixelScreenCo[3];  
 
2608
                                                                                        pixelScreenCo[1] = (float)(curarea->winy/2.0f)+(curarea->winy/2.0f)*pixelScreenCo[1]/pixelScreenCo[3];
 
2609
                                                                                        pixelScreenCo[2] = pixelScreenCo[2]/pixelScreenCo[3]; /* Use the depth for bucket point occlusion */
 
2610
                                                                                }
 
2611
                                                                                
 
2612
                                                                                if (ps->do_occlude==0 || !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo)) {
 
2613
                                                                                        
 
2614
                                                                                        /* Only bother calculating the weights if we intersect */
 
2615
                                                                                        if (ps->do_mask_normal || ps->dm_mtface_clone) {
 
2616
#if 0
 
2617
                                                                                                /* This is not QUITE correct since UV is not inside the UV's but good enough for seams */
 
2618
                                                                                                if (side) {
 
2619
                                                                                                        BarycentricWeights2f(uv, tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], w);
 
2620
                                                                                                }
 
2621
                                                                                                else {
 
2622
                                                                                                        BarycentricWeights2f(uv, tf_uv_pxoffset[0], tf_uv_pxoffset[1], tf_uv_pxoffset[2], w);
 
2623
                                                                                                }
 
2624
#endif
 
2625
#if 1
 
2626
                                                                                                /* Cheat, we know where we are along the edge so work out the weights from that */
 
2627
                                                                                                fac = fac1 + (fac * (fac2-fac1));
 
2628
                                                                                                w[0]=w[1]=w[2]= 0.0;
 
2629
                                                                                                if (side) {
 
2630
                                                                                                        w[fidx1?fidx1-1:0] = fac;
 
2631
                                                                                                        w[fidx2?fidx2-1:0] = 1.0-fac;
 
2632
                                                                                                }
 
2633
                                                                                                else {
 
2634
                                                                                                        w[fidx1] = fac;
 
2635
                                                                                                        w[fidx2] = 1.0-fac;
 
2636
                                                                                                }
 
2637
#endif
 
2638
                                                                                        }
 
2639
                                                                                        
 
2640
                                                                                        /* a pitty we need to get the worldspace pixel location here */
 
2641
                                                                                        if(G.vd->flag & V3D_CLIPPING) {
 
2642
                                                                                                if (side)       VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
 
2643
                                                                                                else            VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
 
2644
                                                                                                
 
2645
                                                                                                Mat4MulVecfl(ps->ob->obmat, wco);
 
2646
                                                                                                if(view3d_test_clipping(G.vd, wco)) {
 
2647
                                                                                                        continue; /* Watch out that no code below this needs to run */
 
2648
                                                                                                }
 
2649
                                                                                        }
 
2650
                                                                                        
 
2651
                                                                                        mask = project_paint_uvpixel_mask(ps, face_index, side, w);
 
2652
                                                                                        
 
2653
                                                                                        if (mask > 0.0f) {
 
2654
                                                                                                BLI_linklist_prepend_arena(
 
2655
                                                                                                        bucketPixelNodes,
 
2656
                                                                                                        project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, side, w),
 
2657
                                                                                                        arena
 
2658
                                                                                                );
 
2659
                                                                                        }
 
2660
                                                                                        
 
2661
                                                                                }
 
2662
                                                                        }
 
2663
                                                                        else if (has_x_isect) {
 
2664
                                                                                /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
 
2665
                                                                                break;
 
2666
                                                                        }
 
2667
                                                                }
 
2668
                                                                
 
2669
#if 0                                                   /* TODO - investigate why this dosnt work sometimes! it should! */
 
2670
                                                                /* no intersection for this entire row, after some intersection above means we can quit now */
 
2671
                                                                if (has_x_isect==0 && has_isect) { 
 
2672
                                                                        break;
 
2673
                                                                }
 
2674
#endif
 
2675
                                                        }
 
2676
                                                }
 
2677
                                        }
 
2678
                                }
 
2679
                        }
 
2680
                }
 
2681
        }
 
2682
#endif // PROJ_DEBUG_NOSEAMBLEED
 
2683
}
 
2684
 
 
2685
 
 
2686
/* takes floating point screenspace min/max and returns int min/max to be used as indicies for ps->bucketRect, ps->bucketFlags */
 
2687
static void project_paint_bucket_bounds(const ProjPaintState *ps, const float min[2], const float max[2], int bucketMin[2], int bucketMax[2])
 
2688
{
 
2689
        /* divide by bucketWidth & bucketHeight so the bounds are offset in bucket grid units */
 
2690
        bucketMin[0] = (int)(((float)(min[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 0.5f; /* these offsets of 0.5 and 1.5 seem odd but they are correct */
 
2691
        bucketMin[1] = (int)(((float)(min[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 0.5f;
 
2692
        
 
2693
        bucketMax[0] = (int)(((float)(max[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 1.5f;
 
2694
        bucketMax[1] = (int)(((float)(max[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 1.5f;  
 
2695
        
 
2696
        /* incase the rect is outside the mesh 2d bounds */
 
2697
        CLAMP(bucketMin[0], 0, ps->buckets_x);
 
2698
        CLAMP(bucketMin[1], 0, ps->buckets_y);
 
2699
        
 
2700
        CLAMP(bucketMax[0], 0, ps->buckets_x);
 
2701
        CLAMP(bucketMax[1], 0, ps->buckets_y);
 
2702
}
 
2703
 
 
2704
/* set bucket_bounds to a screen space-aligned floating point bound-box */
 
2705
static void project_bucket_bounds(const ProjPaintState *ps, const int bucket_x, const int bucket_y, rctf *bucket_bounds)
 
2706
{
 
2707
        bucket_bounds->xmin =   ps->screenMin[0]+((bucket_x)*(ps->screen_width / ps->buckets_x));               /* left */
 
2708
        bucket_bounds->xmax =   ps->screenMin[0]+((bucket_x+1)*(ps->screen_width / ps->buckets_x));     /* right */
 
2709
        
 
2710
        bucket_bounds->ymin =   ps->screenMin[1]+((bucket_y)*(ps->screen_height / ps->buckets_y));              /* bottom */
 
2711
        bucket_bounds->ymax =   ps->screenMin[1]+((bucket_y+1)*(ps->screen_height  / ps->buckets_y));   /* top */
 
2712
}
 
2713
 
 
2714
/* Fill this bucket with pixels from the faces that intersect it.
 
2715
 * 
 
2716
 * have bucket_bounds as an argument so we don;t need to give bucket_x/y the rect function needs */
 
2717
static void project_bucket_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, rctf *bucket_bounds)
 
2718
{
 
2719
        LinkNode *node;
 
2720
        int face_index, image_index;
 
2721
        ImBuf *ibuf = NULL;
 
2722
        MTFace *tf;
 
2723
        
 
2724
        Image *tpage_last = NULL;
 
2725
        
 
2726
 
 
2727
        if (ps->image_tot==1) {
 
2728
                /* Simple loop, no context switching */
 
2729
                ibuf = ps->projImages[0].ibuf;
 
2730
                
 
2731
                for (node = ps->bucketFaces[bucket_index]; node; node= node->next) { 
 
2732
                        project_paint_face_init(ps, thread_index, bucket_index, (int)node->link, 0, bucket_bounds, ibuf);
 
2733
                }
 
2734
        }
 
2735
        else {
 
2736
                
 
2737
                /* More complicated loop, switch between images */
 
2738
                for (node = ps->bucketFaces[bucket_index]; node; node= node->next) {
 
2739
                        face_index = (int)node->link;
 
2740
                                
 
2741
                        /* Image context switching */
 
2742
                        tf = ps->dm_mtface+face_index;
 
2743
                        if (tpage_last != tf->tpage) {
 
2744
                                tpage_last = tf->tpage;
 
2745
                                
 
2746
                                image_index = -1; /* sanity check */
 
2747
                                
 
2748
                                for (image_index=0; image_index < ps->image_tot; image_index++) {
 
2749
                                        if (ps->projImages[image_index].ima == tpage_last) {
 
2750
                                                ibuf = ps->projImages[image_index].ibuf;
 
2751
                                                break;
 
2752
                                        }
 
2753
                                }
 
2754
                        }
 
2755
                        /* context switching done */
 
2756
                        
 
2757
                        project_paint_face_init(ps, thread_index, bucket_index, face_index, image_index, bucket_bounds, ibuf);
 
2758
                        
 
2759
                }
 
2760
        }
 
2761
        
 
2762
        ps->bucketFlags[bucket_index] |= PROJ_BUCKET_INIT;
 
2763
}
 
2764
 
 
2765
 
 
2766
/* We want to know if a bucket and a face overlap in screen-space
 
2767
 * 
 
2768
 * Note, if this ever returns false positives its not that bad, since a face in the bounding area will have its pixels
 
2769
 * calculated when it might not be needed later, (at the moment at least)
 
2770
 * obviously it shouldn't have bugs though */
 
2771
 
 
2772
static int project_bucket_face_isect(ProjPaintState *ps, float min[2], float max[2], int bucket_x, int bucket_y, int bucket_index, const MFace *mf)
 
2773
{
 
2774
        /* TODO - replace this with a tricker method that uses sideofline for all screenCoords's edges against the closest bucket corner */
 
2775
        rctf bucket_bounds;
 
2776
        float p1[2], p2[2], p3[2], p4[2];
 
2777
        float *v, *v1,*v2,*v3,*v4;
 
2778
        int fidx;
 
2779
        
 
2780
        project_bucket_bounds(ps, bucket_x, bucket_y, &bucket_bounds);
 
2781
        
 
2782
        /* Is one of the faces verts in the bucket bounds? */
 
2783
        
 
2784
        fidx = mf->v4 ? 3:2;
 
2785
        do {
 
2786
                v = ps->screenCoords[ (*(&mf->v1 + fidx)) ];
 
2787
                if (BLI_in_rctf(&bucket_bounds, v[0], v[1])) {
 
2788
                        return 1;
 
2789
                }
 
2790
        } while (fidx--);
 
2791
        
 
2792
        v1 = ps->screenCoords[mf->v1];
 
2793
        v2 = ps->screenCoords[mf->v2];
 
2794
        v3 = ps->screenCoords[mf->v3];
 
2795
        if (mf->v4) {
 
2796
                v4 = ps->screenCoords[mf->v4];
 
2797
        }
 
2798
        
 
2799
        p1[0] = bucket_bounds.xmin; p1[1] = bucket_bounds.ymin;
 
2800
        p2[0] = bucket_bounds.xmin;     p2[1] = bucket_bounds.ymax;
 
2801
        p3[0] = bucket_bounds.xmax;     p3[1] = bucket_bounds.ymax;
 
2802
        p4[0] = bucket_bounds.xmax;     p4[1] = bucket_bounds.ymin;
 
2803
                
 
2804
        if (mf->v4) {
 
2805
                if(     IsectPQ2Df(p1, v1, v2, v3, v4) || IsectPQ2Df(p2, v1, v2, v3, v4) || IsectPQ2Df(p3, v1, v2, v3, v4) || IsectPQ2Df(p4, v1, v2, v3, v4) ||
 
2806
                        /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */
 
2807
                        (IsectLL2Df(p1, p2, v1, v2) || IsectLL2Df(p1, p2, v2, v3) || IsectLL2Df(p1, p2, v3, v4)) ||
 
2808
                        (IsectLL2Df(p2, p3, v1, v2) || IsectLL2Df(p2, p3, v2, v3) || IsectLL2Df(p2, p3, v3, v4)) ||
 
2809
                        (IsectLL2Df(p3, p4, v1, v2) || IsectLL2Df(p3, p4, v2, v3) || IsectLL2Df(p3, p4, v3, v4)) ||
 
2810
                        (IsectLL2Df(p4, p1, v1, v2) || IsectLL2Df(p4, p1, v2, v3) || IsectLL2Df(p4, p1, v3, v4))
 
2811
                ) {
 
2812
                        return 1;
 
2813
                }
 
2814
        }
 
2815
        else {
 
2816
                if(     IsectPT2Df(p1, v1, v2, v3) || IsectPT2Df(p2, v1, v2, v3) || IsectPT2Df(p3, v1, v2, v3) || IsectPT2Df(p4, v1, v2, v3) ||
 
2817
                        /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */
 
2818
                        (IsectLL2Df(p1, p2, v1, v2) || IsectLL2Df(p1, p2, v2, v3)) ||
 
2819
                        (IsectLL2Df(p2, p3, v1, v2) || IsectLL2Df(p2, p3, v2, v3)) ||
 
2820
                        (IsectLL2Df(p3, p4, v1, v2) || IsectLL2Df(p3, p4, v2, v3)) ||
 
2821
                        (IsectLL2Df(p4, p1, v1, v2) || IsectLL2Df(p4, p1, v2, v3))
 
2822
                ) {
 
2823
                        return 1;
 
2824
                }
 
2825
        }
 
2826
 
 
2827
        return 0;
 
2828
}
 
2829
 
 
2830
/* Add faces to the bucket but dont initialize its pixels
 
2831
 * TODO - when painting occluded, sort the faces on their min-Z and only add faces that faces that are not occluded */
 
2832
static void project_paint_delayed_face_init(ProjPaintState *ps, const MFace *mf, const MTFace *tf, const int face_index)
 
2833
{
 
2834
        float min[2], max[2], *vCoSS;
 
2835
        int bucketMin[2], bucketMax[2]; /* for  ps->bucketRect indexing */
 
2836
        int fidx, bucket_x, bucket_y, bucket_index;
 
2837
        int has_x_isect = -1, has_isect = 0; /* for early loop exit */
 
2838
        MemArena *arena = ps->arena_mt[0]; /* just use the first thread arena since threading has not started yet */
 
2839
        
 
2840
        INIT_MINMAX2(min, max);
 
2841
        
 
2842
        fidx = mf->v4 ? 3:2;
 
2843
        do {
 
2844
                vCoSS = ps->screenCoords[ *(&mf->v1 + fidx) ];
 
2845
                DO_MINMAX2(vCoSS, min, max);
 
2846
        } while (fidx--);
 
2847
        
 
2848
        project_paint_bucket_bounds(ps, min, max, bucketMin, bucketMax);
 
2849
        
 
2850
        for (bucket_y = bucketMin[1]; bucket_y < bucketMax[1]; bucket_y++) {
 
2851
                has_x_isect = 0;
 
2852
                for (bucket_x = bucketMin[0]; bucket_x < bucketMax[0]; bucket_x++) {
 
2853
                        
 
2854
                        bucket_index = bucket_x + (bucket_y * ps->buckets_x);
 
2855
                        
 
2856
                        if (project_bucket_face_isect(ps, min, max, bucket_x, bucket_y, bucket_index, mf)) {
 
2857
                                BLI_linklist_prepend_arena(
 
2858
                                        &ps->bucketFaces[ bucket_index ],
 
2859
                                        SET_INT_IN_POINTER(face_index), /* cast to a pointer to shut up the compiler */
 
2860
                                        arena
 
2861
                                );
 
2862
                                
 
2863
                                has_x_isect = has_isect = 1;
 
2864
                        }
 
2865
                        else if (has_x_isect) {
 
2866
                                /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
 
2867
                                break;
 
2868
                        }
 
2869
                }
 
2870
                
 
2871
                /* no intersection for this entire row, after some intersection above means we can quit now */
 
2872
                if (has_x_isect==0 && has_isect) { 
 
2873
                        break;
 
2874
                }
 
2875
        }
 
2876
        
 
2877
#ifndef PROJ_DEBUG_NOSEAMBLEED
 
2878
        if (ps->seam_bleed_px > 0.0f) {
 
2879
                if (!mf->v4) {
 
2880
                        ps->faceSeamFlags[face_index] |= PROJ_FACE_NOSEAM4; /* so this wont show up as an untagged edge */
 
2881
                }
 
2882
                **ps->faceSeamUVs[face_index] = MAXFLOAT; /* set as uninitialized */
 
2883
        }
 
2884
#endif
 
2885
}
 
2886
 
 
2887
/* run once per stroke before projection painting */
 
2888
static void project_paint_begin(ProjPaintState *ps, short mval[2])
 
2889
{       
 
2890
        /* Viewport vars */
 
2891
        float mat[3][3];
 
2892
        
 
2893
        float no[3];
 
2894
        
 
2895
        float (*projScreenCo)[4]; /* Note, we could have 4D vectors are only needed for */
 
2896
        float projMargin;
 
2897
        /* Image Vars - keep track of images we have used */
 
2898
        LinkNode *image_LinkList = NULL;
 
2899
        LinkNode *node;
 
2900
        
 
2901
        ProjPaintImage *projIma;
 
2902
        Image *tpage_last = NULL;
 
2903
        
 
2904
        /* Face vars */
 
2905
        MFace *mf;
 
2906
        MTFace *tf;
 
2907
        
 
2908
        int a, i; /* generic looping vars */
 
2909
        int image_index = -1, face_index;
 
2910
        
 
2911
        MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
 
2912
        
 
2913
        /* ---- end defines ---- */
 
2914
        
 
2915
        /* paint onto the derived mesh */
 
2916
        ps->dm = mesh_get_derived_final(ps->ob, get_viewedit_datamask());
 
2917
        
 
2918
        if ( !CustomData_has_layer( &ps->dm->faceData, CD_MTFACE) ) {
 
2919
                ps->dm = NULL;
 
2920
                return; 
 
2921
        }
 
2922
        ps->dm_mvert = ps->dm->getVertArray(ps->dm);
 
2923
        ps->dm_mface = ps->dm->getFaceArray(ps->dm);
 
2924
        ps->dm_mtface= ps->dm->getFaceDataArray(ps->dm, CD_MTFACE);
 
2925
        
 
2926
        ps->dm_totvert = ps->dm->getNumVerts(ps->dm);
 
2927
        ps->dm_totface = ps->dm->getNumFaces(ps->dm);
 
2928
        
 
2929
        /* use clone mtface? */
 
2930
        
 
2931
        
 
2932
        /* Note, use the original mesh for getting the clone and mask layer index
 
2933
         * this avoids re-generating the derived mesh just to get the new index */
 
2934
        if (ps->do_layer_clone) {
 
2935
                //int layer_num = CustomData_get_clone_layer(&ps->dm->faceData, CD_MTFACE);
 
2936
                int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
 
2937
                if (layer_num != -1)
 
2938
                        ps->dm_mtface_clone = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
 
2939
                
 
2940
                if (ps->dm_mtface_clone==NULL || ps->dm_mtface_clone==ps->dm_mtface) {
 
2941
                        ps->do_layer_clone = 0;
 
2942
                        ps->dm_mtface_clone= NULL;
 
2943
                }
 
2944
        }
 
2945
        
 
2946
        if (ps->do_layer_mask) {
 
2947
                //int layer_num = CustomData_get_mask_layer(&ps->dm->faceData, CD_MTFACE);
 
2948
                int layer_num = CustomData_get_mask_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
 
2949
                if (layer_num != -1)
 
2950
                        ps->dm_mtface_mask = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
 
2951
                
 
2952
                if (ps->dm_mtface_mask==NULL || ps->dm_mtface_mask==ps->dm_mtface) {
 
2953
                        ps->do_layer_mask = 0;
 
2954
                        ps->dm_mtface_mask = NULL;
 
2955
                }
 
2956
        }
 
2957
        
 
2958
 
 
2959
        
 
2960
        ps->viewDir[0] = 0.0f;
 
2961
        ps->viewDir[1] = 0.0f;
 
2962
        ps->viewDir[2] = 1.0f;
 
2963
        
 
2964
        view3d_get_object_project_mat(curarea, ps->ob, ps->projectMat, ps->viewMat);
 
2965
        
 
2966
        /* viewDir - object relative */
 
2967
        Mat4Invert(ps->ob->imat, ps->ob->obmat);
 
2968
        Mat3CpyMat4(mat, G.vd->viewinv);
 
2969
        Mat3MulVecfl(mat, ps->viewDir);
 
2970
        Mat3CpyMat4(mat, ps->ob->imat);
 
2971
        Mat3MulVecfl(mat, ps->viewDir);
 
2972
        Normalize(ps->viewDir);
 
2973
        
 
2974
        /* viewPos - object relative */
 
2975
        VECCOPY(ps->viewPos, G.vd->viewinv[3]);
 
2976
        Mat3CpyMat4(mat, ps->ob->imat);
 
2977
        Mat3MulVecfl(mat, ps->viewPos);
 
2978
        VecAddf(ps->viewPos, ps->viewPos, ps->ob->imat[3]);
 
2979
        
 
2980
        {       /* only use these for running 'get_view3d_viewplane' */
 
2981
                rctf viewplane;
 
2982
                
 
2983
                ps->is_ortho = get_view3d_viewplane(curarea->winx, curarea->winy, &viewplane, &ps->clipsta, &ps->clipend, NULL);
 
2984
                
 
2985
                //printf("%f %f\n", ps->clipsta, ps->clipend);
 
2986
                if (ps->is_ortho) { /* only needed for ortho */
 
2987
                        float fac = 2.0f / (ps->clipend - ps->clipsta);  
 
2988
                        ps->clipsta *= fac;
 
2989
                        ps->clipend *= fac;
 
2990
                }
 
2991
                else {
 
2992
                        /* TODO - can we even adjust for clip start/end? */
 
2993
                }
 
2994
                
 
2995
        }
 
2996
        
 
2997
        ps->is_airbrush = (ps->brush->flag & BRUSH_AIRBRUSH) ? 1 : 0;
 
2998
        
 
2999
        ps->is_texbrush = (ps->brush->mtex[ps->brush->texact] && ps->brush->mtex[ps->brush->texact]->tex) ? 1 : 0;
 
3000
 
 
3001
        
 
3002
        /* calculate vert screen coords
 
3003
         * run this early so we can calculate the x/y resolution of our bucket rect */
 
3004
        INIT_MINMAX2(ps->screenMin, ps->screenMax);
 
3005
        
 
3006
        ps->screenCoords = MEM_mallocN(sizeof(float) * ps->dm_totvert * 4, "ProjectPaint ScreenVerts");
 
3007
        projScreenCo = ps->screenCoords;
 
3008
        
 
3009
        if (ps->is_ortho) {
 
3010
                for(a=0; a < ps->dm_totvert; a++, projScreenCo++) {
 
3011
                        VECCOPY((*projScreenCo), ps->dm_mvert[a].co);
 
3012
                        Mat4MulVecfl(ps->projectMat, (*projScreenCo));
 
3013
                        
 
3014
                        /* screen space, not clamped */
 
3015
                        (*projScreenCo)[0] = (float)(curarea->winx/2.0f)+(curarea->winx/2.0f)*(*projScreenCo)[0];
 
3016
                        (*projScreenCo)[1] = (float)(curarea->winy/2.0f)+(curarea->winy/2.0f)*(*projScreenCo)[1];
 
3017
                        DO_MINMAX2((*projScreenCo), ps->screenMin, ps->screenMax);
 
3018
                }
 
3019
        }
 
3020
        else {
 
3021
                for(a=0; a < ps->dm_totvert; a++, projScreenCo++) {
 
3022
                        VECCOPY((*projScreenCo), ps->dm_mvert[a].co);
 
3023
                        (*projScreenCo)[3] = 1.0f;
 
3024
 
 
3025
                        Mat4MulVec4fl(ps->projectMat, (*projScreenCo));
 
3026
 
 
3027
                        
 
3028
                        if ((*projScreenCo)[3] > ps->clipsta) {
 
3029
                                /* screen space, not clamped */
 
3030
                                (*projScreenCo)[0] = (float)(curarea->winx/2.0f)+(curarea->winx/2.0f)*(*projScreenCo)[0]/(*projScreenCo)[3];
 
3031
                                (*projScreenCo)[1] = (float)(curarea->winy/2.0f)+(curarea->winy/2.0f)*(*projScreenCo)[1]/(*projScreenCo)[3];
 
3032
                                (*projScreenCo)[2] = (*projScreenCo)[2]/(*projScreenCo)[3]; /* Use the depth for bucket point occlusion */
 
3033
                                DO_MINMAX2((*projScreenCo), ps->screenMin, ps->screenMax);
 
3034
                        }
 
3035
                        else {
 
3036
                                /* TODO - deal with cases where 1 side of a face goes behind the view ?
 
3037
                                 * 
 
3038
                                 * After some research this is actually very tricky, only option is to
 
3039
                                 * clip the derived mesh before painting, which is a Pain */
 
3040
                                (*projScreenCo)[0] = MAXFLOAT;
 
3041
                        }
 
3042
                }
 
3043
        }
 
3044
        
 
3045
        /* If this border is not added we get artifacts for faces that
 
3046
         * have a parallel edge and at the bounds of the the 2D projected verts eg
 
3047
         * - a single screen aligned quad */
 
3048
        projMargin = (ps->screenMax[0] - ps->screenMin[0]) * 0.000001f;
 
3049
        ps->screenMax[0] += projMargin;
 
3050
        ps->screenMin[0] -= projMargin;
 
3051
        projMargin = (ps->screenMax[1] - ps->screenMin[1]) * 0.000001f;
 
3052
        ps->screenMax[1] += projMargin;
 
3053
        ps->screenMin[1] -= projMargin;
 
3054
        
 
3055
#ifdef PROJ_DEBUG_WINCLIP
 
3056
        CLAMP(ps->screenMin[0], -ps->brush->size, curarea->winx + ps->brush->size);
 
3057
        CLAMP(ps->screenMax[0], -ps->brush->size, curarea->winx + ps->brush->size);
 
3058
 
 
3059
        CLAMP(ps->screenMin[1], -ps->brush->size, curarea->winy + ps->brush->size);
 
3060
        CLAMP(ps->screenMax[1], -ps->brush->size, curarea->winy + ps->brush->size);
 
3061
#endif
 
3062
        
 
3063
        /* only for convenience */
 
3064
        ps->screen_width  = ps->screenMax[0] - ps->screenMin[0];
 
3065
        ps->screen_height = ps->screenMax[1] - ps->screenMin[1];
 
3066
        
 
3067
        ps->buckets_x = (int)(ps->screen_width / (((float)ps->brush->size) / PROJ_BUCKET_BRUSH_DIV));
 
3068
        ps->buckets_y = (int)(ps->screen_height / (((float)ps->brush->size) / PROJ_BUCKET_BRUSH_DIV));
 
3069
        
 
3070
        /* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */
 
3071
        
 
3072
        /* really high values could cause problems since it has to allocate a few
 
3073
         * (ps->buckets_x*ps->buckets_y) sized arrays  */
 
3074
        CLAMP(ps->buckets_x, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
 
3075
        CLAMP(ps->buckets_y, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
 
3076
        
 
3077
        ps->bucketRect = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketRect");
 
3078
        ps->bucketFaces= (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
 
3079
        
 
3080
        ps->bucketFlags= (unsigned char *)MEM_callocN(sizeof(char) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
 
3081
#ifndef PROJ_DEBUG_NOSEAMBLEED
 
3082
        if (ps->seam_bleed_px > 0.0f) {
 
3083
                ps->vertFaces= (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->dm_totvert, "paint-vertFaces");
 
3084
                ps->faceSeamFlags = (char *)MEM_callocN(sizeof(char) * ps->dm_totface, "paint-faceSeamFlags");
 
3085
                ps->faceSeamUVs= MEM_mallocN(sizeof(float) * ps->dm_totface * 8, "paint-faceSeamUVs");
 
3086
        }
 
3087
#endif
 
3088
        
 
3089
        /* Thread stuff
 
3090
         * 
 
3091
         * very small brushes run a lot slower multithreaded since the advantage with
 
3092
         * threads is being able to fill in multiple buckets at once.
 
3093
         * Only use threads for bigger brushes. */
 
3094
        
 
3095
        if (G.scene->r.mode & R_FIXED_THREADS) {
 
3096
                ps->thread_tot = G.scene->r.threads;
 
3097
        }
 
3098
        else {
 
3099
                ps->thread_tot = BLI_system_thread_count();
 
3100
        }
 
3101
        for (a=0; a<ps->thread_tot; a++) {
 
3102
                ps->arena_mt[a] = BLI_memarena_new(1<<16);
 
3103
        }
 
3104
        
 
3105
        arena = ps->arena_mt[0]; 
 
3106
        
 
3107
        if (ps->do_backfacecull && ps->do_mask_normal) {
 
3108
                MVert *v = ps->dm_mvert;
 
3109
                float viewDirPersp[3];
 
3110
                
 
3111
                ps->vertFlags = MEM_callocN(sizeof(char) * ps->dm_totvert, "paint-vertFlags");
 
3112
                
 
3113
                for(a=0; a < ps->dm_totvert; a++, v++) {
 
3114
                        no[0] = (float)(v->no[0] / 32767.0f);
 
3115
                        no[1] = (float)(v->no[1] / 32767.0f);
 
3116
                        no[2] = (float)(v->no[2] / 32767.0f);
 
3117
                        
 
3118
                        if (ps->is_ortho) {
 
3119
                                if (NormalizedVecAngle2(ps->viewDir, no) >= ps->normal_angle) { /* 1 vert of this face is towards us */
 
3120
                                        ps->vertFlags[a] |= PROJ_VERT_CULL;
 
3121
                                }
 
3122
                        }
 
3123
                        else {
 
3124
                                VecSubf(viewDirPersp, ps->viewPos, v->co);
 
3125
                                Normalize(viewDirPersp);
 
3126
                                if (NormalizedVecAngle2(viewDirPersp, no) >= ps->normal_angle) { /* 1 vert of this face is towards us */
 
3127
                                        ps->vertFlags[a] |= PROJ_VERT_CULL;
 
3128
                                }
 
3129
                        }
 
3130
                }
 
3131
        }
 
3132
        
 
3133
        /* setup clone offset */
 
3134
        if (ps->tool == PAINT_TOOL_CLONE) {
 
3135
                float projCo[4];
 
3136
                float *curs= give_cursor();
 
3137
                VECCOPY(projCo, curs);
 
3138
                Mat4MulVecfl(ps->ob->imat, projCo);
 
3139
                
 
3140
                projCo[3] = 1.0f;
 
3141
                Mat4MulVec4fl(ps->projectMat, projCo);
 
3142
                ps->cloneOffset[0] = mval[0] - ((float)(curarea->winx/2.0f)+(curarea->winx/2.0f)*projCo[0]/projCo[3]);
 
3143
                ps->cloneOffset[1] = mval[1] - ((float)(curarea->winy/2.0f)+(curarea->winy/2.0f)*projCo[1]/projCo[3]);
 
3144
                
 
3145
                // printf("%f %f   %f %f %f\n", ps->cloneOffset[0], ps->cloneOffset[1], curs[0], curs[1], curs[2]);
 
3146
                
 
3147
        }       
 
3148
 
 
3149
        
 
3150
        
 
3151
        for(face_index = 0, tf = ps->dm_mtface, mf = ps->dm_mface; face_index < ps->dm_totface; mf++, tf++, face_index++) {
 
3152
                
 
3153
#ifndef PROJ_DEBUG_NOSEAMBLEED
 
3154
                /* add face user if we have bleed enabled, set the UV seam flags later */
 
3155
                /* annoying but we need to add all faces even ones we never use elsewhere */
 
3156
                if (ps->seam_bleed_px > 0.0f) {
 
3157
                        BLI_linklist_prepend_arena(&ps->vertFaces[mf->v1], (void *)face_index, arena);
 
3158
                        BLI_linklist_prepend_arena(&ps->vertFaces[mf->v2], (void *)face_index, arena);
 
3159
                        BLI_linklist_prepend_arena(&ps->vertFaces[mf->v3], (void *)face_index, arena);
 
3160
                        if (mf->v4) {
 
3161
                                BLI_linklist_prepend_arena(&ps->vertFaces[ mf->v4 ], (void *)face_index, arena);
 
3162
                        }
 
3163
                }
 
3164
#endif
 
3165
                
 
3166
                if (tf->tpage && ((G.f & G_FACESELECT)==0 || mf->flag & ME_FACE_SEL)) {
 
3167
                        
 
3168
                        float *v1coSS, *v2coSS, *v3coSS, *v4coSS;
 
3169
                        
 
3170
                        v1coSS = ps->screenCoords[mf->v1]; 
 
3171
                        v2coSS = ps->screenCoords[mf->v2]; 
 
3172
                        v3coSS = ps->screenCoords[mf->v3];
 
3173
                        if (mf->v4) {
 
3174
                                v4coSS = ps->screenCoords[mf->v4]; 
 
3175
                        }
 
3176
                        
 
3177
                        
 
3178
                        if (!ps->is_ortho) {
 
3179
                                if (    v1coSS[0]==MAXFLOAT ||
 
3180
                                                v2coSS[0]==MAXFLOAT ||
 
3181
                                                v3coSS[0]==MAXFLOAT ||
 
3182
                                                (mf->v4 && v4coSS[0]==MAXFLOAT)
 
3183
                                ) {
 
3184
                                        continue;
 
3185
                                }
 
3186
                        }
 
3187
                        
 
3188
#ifdef PROJ_DEBUG_WINCLIP
 
3189
                        /* ignore faces outside the view */
 
3190
                        if (
 
3191
                                   (v1coSS[0] < ps->screenMin[0] &&
 
3192
                                        v2coSS[0] < ps->screenMin[0] &&
 
3193
                                        v3coSS[0] < ps->screenMin[0] &&
 
3194
                                        (mf->v4 && v4coSS[0] < ps->screenMin[0])) ||
 
3195
                                        
 
3196
                                   (v1coSS[0] > ps->screenMax[0] &&
 
3197
                                        v2coSS[0] > ps->screenMax[0] &&
 
3198
                                        v3coSS[0] > ps->screenMax[0] &&
 
3199
                                        (mf->v4 && v4coSS[0] > ps->screenMax[0])) ||
 
3200
                                        
 
3201
                                   (v1coSS[1] < ps->screenMin[1] &&
 
3202
                                        v2coSS[1] < ps->screenMin[1] &&
 
3203
                                        v3coSS[1] < ps->screenMin[1] &&
 
3204
                                        (mf->v4 && v4coSS[1] < ps->screenMin[1])) ||
 
3205
                                        
 
3206
                                   (v1coSS[1] > ps->screenMax[1] &&
 
3207
                                        v2coSS[1] > ps->screenMax[1] &&
 
3208
                                        v3coSS[1] > ps->screenMax[1] &&
 
3209
                                        (mf->v4 && v4coSS[1] > ps->screenMax[1]))
 
3210
                        ) {
 
3211
                                continue;
 
3212
                        }
 
3213
                        
 
3214
#endif //PROJ_DEBUG_WINCLIP
 
3215
        
 
3216
                        
 
3217
                        if (ps->do_backfacecull) {
 
3218
                                if (ps->do_mask_normal) {
 
3219
                                        /* Since we are interpolating the normals of faces, we want to make 
 
3220
                                         * sure all the verts are pointing away from the view,
 
3221
                                         * not just the face */
 
3222
                                        if (    (ps->vertFlags[mf->v1] & PROJ_VERT_CULL) &&
 
3223
                                                        (ps->vertFlags[mf->v2] & PROJ_VERT_CULL) &&
 
3224
                                                        (ps->vertFlags[mf->v3] & PROJ_VERT_CULL) &&
 
3225
                                                        (mf->v4==0 || ps->vertFlags[mf->v4] & PROJ_VERT_CULL)
 
3226
                                                        
 
3227
                                        ) {
 
3228
                                                continue;
 
3229
                                        }
 
3230
                                }
 
3231
                                else {
 
3232
                                        if (SIDE_OF_LINE(v1coSS, v2coSS, v3coSS) < 0.0f) {
 
3233
                                                continue;
 
3234
                                        }
 
3235
                                        
 
3236
                                }
 
3237
                        }
 
3238
                        
 
3239
                        if (tpage_last != tf->tpage) {
 
3240
                                
 
3241
                                image_index = BLI_linklist_index(image_LinkList, tf->tpage);
 
3242
                                
 
3243
                                if (image_index==-1 && BKE_image_get_ibuf(tf->tpage, NULL)) { /* MemArena dosnt have an append func */
 
3244
                                        BLI_linklist_append(&image_LinkList, tf->tpage);
 
3245
                                        image_index = ps->image_tot;
 
3246
                                        ps->image_tot++;
 
3247
                                }
 
3248
                                
 
3249
                                tpage_last = tf->tpage;
 
3250
                        }
 
3251
                        
 
3252
                        if (image_index != -1) {
 
3253
                                /* Initialize the faces screen pixels */
 
3254
                                /* Add this to a list to initialize later */
 
3255
                                project_paint_delayed_face_init(ps, mf, tf, face_index);
 
3256
                        }
 
3257
                }
 
3258
        }
 
3259
        
 
3260
        /* build an array of images we use*/
 
3261
        projIma = ps->projImages = (ProjPaintImage *)BLI_memarena_alloc(arena, sizeof(ProjPaintImage) * ps->image_tot);
 
3262
        
 
3263
        for (node= image_LinkList, i=0; node; node= node->next, i++, projIma++) {
 
3264
                projIma->ima = node->link;
 
3265
                projIma->touch = 0;
 
3266
                projIma->ibuf = BKE_image_get_ibuf(projIma->ima, NULL);
 
3267
                projIma->partRedrawRect =  BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
 
3268
                memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
 
3269
        }
 
3270
        
 
3271
        /* we have built the array, discard the linked list */
 
3272
        BLI_linklist_free(image_LinkList, NULL);
 
3273
}
 
3274
 
 
3275
static void project_paint_end(ProjPaintState *ps)
 
3276
{
 
3277
        int a;
 
3278
        
 
3279
        /* build undo data from original pixel colors */
 
3280
        if(U.uiflag & USER_GLOBALUNDO) {
 
3281
                ProjPixel *projPixel;
 
3282
                ImBuf *tmpibuf = NULL, *tmpibuf_float = NULL;
 
3283
                LinkNode *pixel_node;
 
3284
                UndoTile *tile;
 
3285
                MemArena *arena = ps->arena_mt[0]; /* threaded arena re-used for non threaded case */
 
3286
                                
 
3287
                int bucket_tot = (ps->buckets_x * ps->buckets_y); /* we could get an X/Y but easier to loop through all possible buckets */
 
3288
                int bucket_index; 
 
3289
                int tile_index;
 
3290
                int x_round, y_round;
 
3291
                int x_tile, y_tile;
 
3292
                int is_float = -1;
 
3293
                
 
3294
                /* context */
 
3295
                ProjPaintImage *last_projIma;
 
3296
                int last_image_index = -1;
 
3297
                int last_tile_width;
 
3298
                
 
3299
                for(a=0, last_projIma=ps->projImages; a < ps->image_tot; a++, last_projIma++) {
 
3300
                        int size = sizeof(UndoTile **) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->y);
 
3301
                        last_projIma->undoRect = (UndoTile **) BLI_memarena_alloc(arena, size);
 
3302
                        memset(last_projIma->undoRect, 0, size);
 
3303
                        last_projIma->ibuf->userflags |= IB_BITMAPDIRTY;
 
3304
                }
 
3305
                
 
3306
                for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) {
 
3307
                        /* loop through all pixels */
 
3308
                        for(pixel_node= ps->bucketRect[bucket_index]; pixel_node; pixel_node= pixel_node->next) {
 
3309
                        
 
3310
                                /* ok we have a pixel, was it modified? */
 
3311
                                projPixel = (ProjPixel *)pixel_node->link;
 
3312
                                
 
3313
                                if (last_image_index != projPixel->image_index) {
 
3314
                                        /* set the context */
 
3315
                                        last_image_index =      projPixel->image_index;
 
3316
                                        last_projIma =          ps->projImages + last_image_index;
 
3317
                                        last_tile_width =       IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x);
 
3318
                                        is_float =                      last_projIma->ibuf->rect_float ? 1 : 0;
 
3319
                                }
 
3320
                                
 
3321
                                
 
3322
                                if (    (is_float == 0 && projPixel->origColor.uint != *projPixel->pixel.uint_pt) || 
 
3323
                                                                
 
3324
                                                (is_float == 1 && 
 
3325
                                                (       projPixel->origColor.f[0] != projPixel->pixel.f_pt[0] || 
 
3326
                                                        projPixel->origColor.f[1] != projPixel->pixel.f_pt[1] ||
 
3327
                                                        projPixel->origColor.f[2] != projPixel->pixel.f_pt[2] ||
 
3328
                                                        projPixel->origColor.f[3] != projPixel->pixel.f_pt[3] ))
 
3329
                                ) {
 
3330
                                        
 
3331
                                        x_tile =  projPixel->x_px >> IMAPAINT_TILE_BITS;
 
3332
                                        y_tile =  projPixel->y_px >> IMAPAINT_TILE_BITS;
 
3333
                                        
 
3334
                                        x_round = x_tile * IMAPAINT_TILE_SIZE;
 
3335
                                        y_round = y_tile * IMAPAINT_TILE_SIZE;
 
3336
                                        
 
3337
                                        tile_index = x_tile + y_tile * last_tile_width;
 
3338
                                        
 
3339
                                        if (last_projIma->undoRect[tile_index]==NULL) {
 
3340
                                                /* add the undo tile from the modified image, then write the original colors back into it */
 
3341
                                                tile = last_projIma->undoRect[tile_index] = undo_init_tile(&last_projIma->ima->id, last_projIma->ibuf, is_float ? (&tmpibuf_float):(&tmpibuf) , x_tile, y_tile);
 
3342
                                        }
 
3343
                                        else {
 
3344
                                                tile = last_projIma->undoRect[tile_index];
 
3345
                                        }
 
3346
                                        
 
3347
                                        /* This is a BIT ODD, but overwrite the undo tiles image info with this pixels original color
 
3348
                                         * because allocating the tiles allong the way slows down painting */
 
3349
                                        
 
3350
                                        if (is_float) {
 
3351
                                                float *rgba_fp = (float *)tile->rect + (((projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE)) * 4;
 
3352
                                                QUATCOPY(rgba_fp, projPixel->origColor.f);
 
3353
                                        }
 
3354
                                        else {
 
3355
                                                ((unsigned int *)tile->rect)[ (projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE ] = projPixel->origColor.uint;
 
3356
                                        }
 
3357
                                }
 
3358
                        }
 
3359
                }
 
3360
                
 
3361
                if (tmpibuf)            IMB_freeImBuf(tmpibuf);
 
3362
                if (tmpibuf_float)      IMB_freeImBuf(tmpibuf_float);
 
3363
        }
 
3364
        /* done calculating undo data */
 
3365
        
 
3366
        MEM_freeN(ps->screenCoords);
 
3367
        MEM_freeN(ps->bucketRect);
 
3368
        MEM_freeN(ps->bucketFaces);
 
3369
        MEM_freeN(ps->bucketFlags);
 
3370
        
 
3371
#ifndef PROJ_DEBUG_NOSEAMBLEED
 
3372
        if (ps->seam_bleed_px > 0.0f) {
 
3373
                MEM_freeN(ps->vertFaces);
 
3374
                MEM_freeN(ps->faceSeamFlags);
 
3375
                MEM_freeN(ps->faceSeamUVs);
 
3376
        }
 
3377
#endif
 
3378
        
 
3379
        if (ps->vertFlags) MEM_freeN(ps->vertFlags);
 
3380
        
 
3381
        for (a=0; a<ps->thread_tot; a++) {
 
3382
                BLI_memarena_free(ps->arena_mt[a]);
 
3383
        }
 
3384
        
 
3385
        ps->dm->release(ps->dm);
 
3386
}
 
3387
 
 
3388
/* Use this rather then mouse_cursor()
 
3389
 * so rotating the view leaves the 3D Cursor on the clone source surface.
 
3390
 */
 
3391
static void project_paint_setCursor(void) {
 
3392
        float *curs = give_cursor();
 
3393
        short mval[2];
 
3394
 
 
3395
        mouse_cursor(); /* set the cursor location on the view X/Y */
 
3396
        getmouseco_areawin(mval);
 
3397
        view_mouse_depth(curs, mval, 1);
 
3398
}
285
3399
 
286
3400
/* 1= an undo, -1 is a redo. */
 
3401
static void partial_redraw_array_init(ImagePaintPartialRedraw *pr)
 
3402
{
 
3403
        int tot = PROJ_BOUNDBOX_SQUARED;
 
3404
        while (tot--) {
 
3405
                pr->x1 = 10000000;
 
3406
                pr->y1 = 10000000;
 
3407
                
 
3408
                pr->x2 = -1;
 
3409
                pr->y2 = -1;
 
3410
                
 
3411
                pr->enabled = 1;
 
3412
                
 
3413
                pr++;
 
3414
        }
 
3415
}
 
3416
 
 
3417
 
 
3418
static int partial_redraw_array_merge(ImagePaintPartialRedraw *pr, ImagePaintPartialRedraw *pr_other, int tot)
 
3419
{
 
3420
        int touch= 0;
 
3421
        while (tot--) {
 
3422
                pr->x1 = MIN2(pr->x1, pr_other->x1);
 
3423
                pr->y1 = MIN2(pr->y1, pr_other->y1);
 
3424
                
 
3425
                pr->x2 = MAX2(pr->x2, pr_other->x2);
 
3426
                pr->y2 = MAX2(pr->y2, pr_other->y2);
 
3427
                
 
3428
                if (pr->x2 != -1)
 
3429
                        touch = 1;
 
3430
                
 
3431
                pr++; pr_other++;
 
3432
        }
 
3433
        
 
3434
        return touch;
 
3435
}
 
3436
 
 
3437
/* Loop over all images on this mesh and update any we have touched */
 
3438
static int project_image_refresh_tagged(ProjPaintState *ps)
 
3439
{
 
3440
        ImagePaintPartialRedraw *pr;
 
3441
        ProjPaintImage *projIma;
 
3442
        int a,i;
 
3443
        int redraw = 0;
 
3444
        
 
3445
        
 
3446
        for (a=0, projIma=ps->projImages; a < ps->image_tot; a++, projIma++) {
 
3447
                if (projIma->touch) {
 
3448
                        /* look over each bound cell */
 
3449
                        for (i=0; i<PROJ_BOUNDBOX_SQUARED; i++) {
 
3450
                                pr = &(projIma->partRedrawRect[i]);
 
3451
                                if (pr->x2 != -1) { /* TODO - use 'enabled' ? */
 
3452
                                        imapaintpartial = *pr;
 
3453
                                        imapaint_image_update(projIma->ima, projIma->ibuf, 1); /*last 1 is for texpaint*/
 
3454
                                        redraw = 1;
 
3455
                                }
 
3456
                        }
 
3457
                        
 
3458
                        projIma->touch = 0; /* clear for reuse */
 
3459
                }
 
3460
        }
 
3461
        
 
3462
        return redraw;
 
3463
}
 
3464
 
 
3465
/* run this per painting onto each mouse location */
 
3466
static int project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2])
 
3467
{
 
3468
        float min_brush[2], max_brush[2];
 
3469
        float size_half = ((float)ps->brush->size) * 0.5f;
 
3470
        
 
3471
        /* so we dont have a bucket bounds that is way too small to paint into */
 
3472
        // if (size_half < 1.0f) size_half = 1.0f; // this dosnt work yet :/
 
3473
        
 
3474
        min_brush[0] = mval_f[0] - size_half;
 
3475
        min_brush[1] = mval_f[1] - size_half;
 
3476
        
 
3477
        max_brush[0] = mval_f[0] + size_half;
 
3478
        max_brush[1] = mval_f[1] + size_half;
 
3479
        
 
3480
        /* offset to make this a valid bucket index */
 
3481
        project_paint_bucket_bounds(ps, min_brush, max_brush, ps->bucketMin, ps->bucketMax);
 
3482
        
 
3483
        /* mouse outside the model areas? */
 
3484
        if (ps->bucketMin[0]==ps->bucketMax[0] || ps->bucketMin[1]==ps->bucketMax[1]) {
 
3485
                return 0;
 
3486
        }
 
3487
        
 
3488
        ps->context_bucket_x = ps->bucketMin[0];
 
3489
        ps->context_bucket_y = ps->bucketMin[1];
 
3490
        return 1;
 
3491
}
 
3492
 
 
3493
static int project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf *bucket_bounds, const float mval[2])
 
3494
{
 
3495
        if (ps->thread_tot > 1)
 
3496
                BLI_lock_thread(LOCK_CUSTOM1);
 
3497
        
 
3498
        //printf("%d %d \n", ps->context_bucket_x, ps->context_bucket_y);
 
3499
        
 
3500
        for ( ; ps->context_bucket_y < ps->bucketMax[1]; ps->context_bucket_y++) {
 
3501
                for ( ; ps->context_bucket_x < ps->bucketMax[0]; ps->context_bucket_x++) {
 
3502
                        
 
3503
                        /* use bucket_bounds for project_bucket_isect_circle and project_bucket_init*/
 
3504
                        project_bucket_bounds(ps, ps->context_bucket_x, ps->context_bucket_y, bucket_bounds);
 
3505
                        
 
3506
                        if (project_bucket_isect_circle(ps->context_bucket_x, ps->context_bucket_y, mval, ps->brush->size * ps->brush->size, bucket_bounds)) {
 
3507
                                *bucket_index = ps->context_bucket_x + (ps->context_bucket_y * ps->buckets_x);
 
3508
                                ps->context_bucket_x++;
 
3509
                                
 
3510
                                if (ps->thread_tot > 1)
 
3511
                                        BLI_unlock_thread(LOCK_CUSTOM1);
 
3512
                                
 
3513
                                return 1;
 
3514
                        }
 
3515
                }
 
3516
                ps->context_bucket_x = ps->bucketMin[0];
 
3517
        }
 
3518
        
 
3519
        if (ps->thread_tot > 1)
 
3520
                BLI_unlock_thread(LOCK_CUSTOM1);
 
3521
        return 0;
 
3522
}
 
3523
 
 
3524
/* Each thread gets one of these, also used as an argument to pass to project_paint_op */
 
3525
typedef struct ProjectHandle {
 
3526
        /* args */
 
3527
        ProjPaintState *ps;
 
3528
        float prevmval[2];
 
3529
        float mval[2];
 
3530
        
 
3531
        /* annoying but we need to have image bounds per thread, then merge into ps->projectPartialRedraws */
 
3532
        ProjPaintImage *projImages;     /* array of partial redraws */
 
3533
        
 
3534
        /* thread settings */
 
3535
        int thread_index;
 
3536
} ProjectHandle;
 
3537
 
 
3538
static void blend_color_mix(unsigned char *cp, const unsigned char *cp1, const unsigned char *cp2, const int fac)
 
3539
{
 
3540
        /* this and other blending modes previously used >>8 instead of /255. both
 
3541
           are not equivalent (>>8 is /256), and the former results in rounding
 
3542
           errors that can turn colors black fast after repeated blending */
 
3543
        const int mfac= 255-fac;
 
3544
 
 
3545
        cp[0]= (mfac*cp1[0]+fac*cp2[0])/255;
 
3546
        cp[1]= (mfac*cp1[1]+fac*cp2[1])/255;
 
3547
        cp[2]= (mfac*cp1[2]+fac*cp2[2])/255;
 
3548
        cp[3]= (mfac*cp1[3]+fac*cp2[3])/255;
 
3549
}
 
3550
 
 
3551
static void blend_color_mix_float(float *cp, const float *cp1, const float *cp2, const float fac)
 
3552
{
 
3553
        const float mfac= 1.0-fac;
 
3554
        cp[0]= mfac*cp1[0] + fac*cp2[0];
 
3555
        cp[1]= mfac*cp1[1] + fac*cp2[1];
 
3556
        cp[2]= mfac*cp1[2] + fac*cp2[2];
 
3557
        cp[3]= mfac*cp1[3] + fac*cp2[3];
 
3558
}
 
3559
 
 
3560
static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask)
 
3561
{
 
3562
        if (ps->is_airbrush==0 && mask < 1.0f) {
 
3563
                projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, ((ProjPixelClone*)projPixel)->clonepx.uint, (int)(alpha*255), ps->blend);
 
3564
                blend_color_mix(projPixel->pixel.ch_pt,  projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask*255));
 
3565
        }
 
3566
        else {
 
3567
                *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, ((ProjPixelClone*)projPixel)->clonepx.uint, (int)(alpha*mask*255), ps->blend);
 
3568
        }
 
3569
}
 
3570
 
 
3571
static void do_projectpaint_clone_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask)
 
3572
{
 
3573
        if (ps->is_airbrush==0 && mask < 1.0f) {
 
3574
                IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, ((ProjPixelClone *)projPixel)->clonepx.f, alpha, ps->blend);
 
3575
                blend_color_mix_float(projPixel->pixel.f_pt,  projPixel->origColor.f, projPixel->newColor.f, mask);
 
3576
        }
 
3577
        else {
 
3578
                IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f, alpha*mask, ps->blend);
 
3579
        }
 
3580
}
 
3581
 
 
3582
/* do_projectpaint_smear*
 
3583
 * 
 
3584
 * note, mask is used to modify the alpha here, this is not correct since it allows
 
3585
 * accumulation of color greater then 'projPixel->mask' however in the case of smear its not 
 
3586
 * really that important to be correct as it is with clone and painting 
 
3587
 */
 
3588
static void do_projectpaint_smear(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask, MemArena *smearArena, LinkNode **smearPixels, float co[2])
 
3589
{
 
3590
        unsigned char rgba_ub[4];
 
3591
        
 
3592
        if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1)==0)
 
3593
                return; 
 
3594
        /* ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */
 
3595
        blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha*mask*255));
 
3596
        BLI_linklist_prepend_arena(smearPixels, (void *)projPixel, smearArena);
 
3597
 
3598
 
 
3599
static void do_projectpaint_smear_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask, MemArena *smearArena, LinkNode **smearPixels_f, float co[2])
 
3600
{
 
3601
        unsigned char rgba_ub[4];
 
3602
        unsigned char rgba_smear[4];
 
3603
        
 
3604
        if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1)==0)
 
3605
                return;
 
3606
        
 
3607
        IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_smear, projPixel->pixel.f_pt);
 
3608
        /* (ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */
 
3609
        blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, rgba_smear, (rgba_ub), (int)(alpha*mask*255)); 
 
3610
        BLI_linklist_prepend_arena(smearPixels_f, (void *)projPixel, smearArena);
 
3611
}
 
3612
 
 
3613
static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask)
 
3614
{
 
3615
        unsigned char rgba_ub[4];
 
3616
        
 
3617
        if (ps->is_texbrush) {
 
3618
                rgba_ub[0] = FTOCHAR(rgba[0] * ps->brush->rgb[0]);
 
3619
                rgba_ub[1] = FTOCHAR(rgba[1] * ps->brush->rgb[1]);
 
3620
                rgba_ub[2] = FTOCHAR(rgba[2] * ps->brush->rgb[2]);
 
3621
                rgba_ub[3] = FTOCHAR(rgba[3]);
 
3622
        }
 
3623
        else {
 
3624
                IMAPAINT_FLOAT_RGB_TO_CHAR(rgba_ub, ps->brush->rgb);
 
3625
                rgba_ub[3] = 255;
 
3626
        }
 
3627
        
 
3628
        if (ps->is_airbrush==0 && mask < 1.0f) {
 
3629
                projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, *((unsigned int *)rgba_ub), (int)(alpha*255), ps->blend);
 
3630
                blend_color_mix(projPixel->pixel.ch_pt,  projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask*255));
 
3631
        }
 
3632
        else {
 
3633
                *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend);
 
3634
        }
 
3635
}
 
3636
 
 
3637
static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask) {
 
3638
        if (ps->is_texbrush) {
 
3639
                rgba[0] *= ps->brush->rgb[0];
 
3640
                rgba[1] *= ps->brush->rgb[1];
 
3641
                rgba[2] *= ps->brush->rgb[2];
 
3642
        }
 
3643
        else {
 
3644
                VECCOPY(rgba, ps->brush->rgb);
 
3645
        }
 
3646
        
 
3647
        if (ps->is_airbrush==0 && mask < 1.0f) {
 
3648
                IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, rgba, alpha, ps->blend);
 
3649
                blend_color_mix_float(projPixel->pixel.f_pt,  projPixel->origColor.f, projPixel->newColor.f, mask);
 
3650
        }
 
3651
        else {
 
3652
                IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, rgba, alpha*mask, ps->blend);
 
3653
        }
 
3654
}
 
3655
 
 
3656
 
 
3657
 
 
3658
/* run this for single and multithreaded painting */
 
3659
static void *do_projectpaint_thread(void *ph_v)
 
3660
{
 
3661
        /* First unpack args from the struct */
 
3662
        ProjPaintState *ps =                    ((ProjectHandle *)ph_v)->ps;
 
3663
        ProjPaintImage *projImages =    ((ProjectHandle *)ph_v)->projImages;
 
3664
        const float *lastpos =                  ((ProjectHandle *)ph_v)->prevmval;
 
3665
        const float *pos =                              ((ProjectHandle *)ph_v)->mval;
 
3666
        const int thread_index =                ((ProjectHandle *)ph_v)->thread_index;
 
3667
        /* Done with args from ProjectHandle */
 
3668
 
 
3669
        LinkNode *node;
 
3670
        ProjPixel *projPixel;
 
3671
        
 
3672
        int last_index = -1;
 
3673
        ProjPaintImage *last_projIma;
 
3674
        ImagePaintPartialRedraw *last_partial_redraw_cell;
 
3675
        
 
3676
        float rgba[4], alpha, dist_nosqrt;
 
3677
        
 
3678
        float brush_size_sqared;
 
3679
        float falloff;
 
3680
        int bucket_index;
 
3681
        int is_floatbuf = 0;
 
3682
        const short tool =  ps->tool;
 
3683
        rctf bucket_bounds;
 
3684
        
 
3685
        /* for smear only */
 
3686
        float pos_ofs[2];
 
3687
        float co[2];
 
3688
        float mask = 1.0f; /* airbrush wont use mask */
 
3689
        unsigned short mask_short;
 
3690
        
 
3691
        LinkNode *smearPixels = NULL;
 
3692
        LinkNode *smearPixels_f = NULL;
 
3693
        MemArena *smearArena = NULL; /* mem arena for this brush projection only */
 
3694
        
 
3695
        
 
3696
        if (tool==PAINT_TOOL_SMEAR) {
 
3697
                pos_ofs[0] = pos[0] - lastpos[0];
 
3698
                pos_ofs[1] = pos[1] - lastpos[1];
 
3699
                
 
3700
                smearArena = BLI_memarena_new(1<<16);
 
3701
        }
 
3702
        
 
3703
        /* avoid a square root with every dist comparison */
 
3704
        brush_size_sqared = ps->brush->size * ps->brush->size; 
 
3705
        
 
3706
        /* printf("brush bounds %d %d %d %d\n", bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */
 
3707
        
 
3708
        while (project_bucket_iter_next(ps, &bucket_index, &bucket_bounds, pos)) {                              
 
3709
                
 
3710
                /* Check this bucket and its faces are initialized */
 
3711
                if (ps->bucketFlags[bucket_index] == PROJ_BUCKET_NULL) {
 
3712
                        /* No pixels initialized */
 
3713
                        project_bucket_init(ps, thread_index, bucket_index, &bucket_bounds);
 
3714
                }
 
3715
 
 
3716
                for (node = ps->bucketRect[bucket_index]; node; node = node->next) {
 
3717
                        
 
3718
                        projPixel = (ProjPixel *)node->link;
 
3719
                        
 
3720
                        /*dist = Vec2Lenf(projPixel->projCoSS, pos);*/ /* correct but uses a sqrtf */
 
3721
                        dist_nosqrt = Vec2Lenf_nosqrt(projPixel->projCoSS, pos);
 
3722
                        
 
3723
                        /*if (dist < s->brush->size) {*/ /* correct but uses a sqrtf */
 
3724
                        if (dist_nosqrt < brush_size_sqared) {
 
3725
                                falloff = brush_sample_falloff_noalpha(ps->brush, sqrtf(dist_nosqrt));
 
3726
                                if (falloff > 0.0f) {
 
3727
                                        if (ps->is_texbrush) {
 
3728
                                                brush_sample_tex(ps->brush, projPixel->projCoSS, rgba);
 
3729
                                                alpha = rgba[3];
 
3730
                                        } else {
 
3731
                                                alpha = 1.0f;
 
3732
                                        }
 
3733
                                        
 
3734
                                        if (ps->is_airbrush) {
 
3735
                                                /* for an aurbrush there is no real mask, so just multiply the alpha by it */
 
3736
                                                alpha *= falloff * ps->brush->alpha;
 
3737
                                                mask = ((float)projPixel->mask)/65535.0f;
 
3738
                                        }
 
3739
                                        else {
 
3740
                                                /* This brush dosnt accumulate so add some curve to the brushes falloff */
 
3741
                                                falloff = 1.0f - falloff;
 
3742
                                                falloff = 1.0f - (falloff * falloff);
 
3743
                                                
 
3744
                                                mask_short = projPixel->mask * (ps->brush->alpha * falloff);
 
3745
                                                if (mask_short > projPixel->mask_max) {
 
3746
                                                        mask = ((float)mask_short)/65535.0f;
 
3747
                                                        projPixel->mask_max = mask_short;
 
3748
                                                }
 
3749
                                                else {
 
3750
                                                        /*mask = ((float)projPixel->mask_max)/65535.0f;*/
 
3751
                                                        
 
3752
                                                        /* Go onto the next pixel */
 
3753
                                                        continue;
 
3754
                                                }
 
3755
                                        }
 
3756
                                        
 
3757
                                        if (alpha > 0.0f) {
 
3758
                                                
 
3759
                                                if (last_index != projPixel->image_index) {
 
3760
                                                        last_index = projPixel->image_index;
 
3761
                                                        last_projIma = projImages + last_index;
 
3762
                                                        
 
3763
                                                        last_projIma->touch = 1;
 
3764
                                                        is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0;
 
3765
                                                }
 
3766
                                                
 
3767
                                                last_partial_redraw_cell = last_projIma->partRedrawRect + projPixel->bb_cell_index;
 
3768
                                                last_partial_redraw_cell->x1 = MIN2(last_partial_redraw_cell->x1, projPixel->x_px);
 
3769
                                                last_partial_redraw_cell->y1 = MIN2(last_partial_redraw_cell->y1, projPixel->y_px);
 
3770
                                                
 
3771
                                                last_partial_redraw_cell->x2 = MAX2(last_partial_redraw_cell->x2, projPixel->x_px+1);
 
3772
                                                last_partial_redraw_cell->y2 = MAX2(last_partial_redraw_cell->y2, projPixel->y_px+1);
 
3773
                                                
 
3774
                                                
 
3775
                                                switch(tool) {
 
3776
                                                case PAINT_TOOL_CLONE:
 
3777
                                                        if (is_floatbuf) {
 
3778
                                                                if (((ProjPixelClone *)projPixel)->clonepx.f[3]) {
 
3779
                                                                        do_projectpaint_clone_f(ps, projPixel, rgba, alpha, mask);
 
3780
                                                                }
 
3781
                                                        }
 
3782
                                                        else {
 
3783
                                                                if (((ProjPixelClone*)projPixel)->clonepx.ch[3]) { 
 
3784
                                                                        do_projectpaint_clone(ps, projPixel, rgba, alpha, mask);
 
3785
                                                                }
 
3786
                                                        }
 
3787
                                                        break;
 
3788
                                                case PAINT_TOOL_SMEAR:
 
3789
                                                        Vec2Subf(co, projPixel->projCoSS, pos_ofs);
 
3790
                                                        
 
3791
                                                        if (is_floatbuf)        do_projectpaint_smear_f(ps, projPixel, rgba, alpha, mask, smearArena, &smearPixels_f, co);
 
3792
                                                        else                            do_projectpaint_smear(ps, projPixel, rgba, alpha, mask, smearArena, &smearPixels, co);
 
3793
                                                        break;
 
3794
                                                default:
 
3795
                                                        if (is_floatbuf)        do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask);
 
3796
                                                        else                            do_projectpaint_draw(ps, projPixel, rgba, alpha, mask);
 
3797
                                                        break;
 
3798
                                                }
 
3799
                                        }
 
3800
                                        /* done painting */
 
3801
                                }
 
3802
                        }
 
3803
                }
 
3804
        }
 
3805
 
 
3806
        
 
3807
        if (tool==PAINT_TOOL_SMEAR) {
 
3808
                
 
3809
                for (node= smearPixels; node; node= node->next) { /* this wont run for a float image */
 
3810
                        projPixel = node->link;
 
3811
                        *projPixel->pixel.uint_pt = ((ProjPixelClone *)projPixel)->clonepx.uint;
 
3812
                }
 
3813
                
 
3814
                for (node= smearPixels_f; node; node= node->next) {
 
3815
                        projPixel = node->link;
 
3816
                        IMAPAINT_CHAR_RGBA_TO_FLOAT(projPixel->pixel.f_pt,  ((ProjPixelClone *)projPixel)->clonepx.ch);
 
3817
                }
 
3818
                
 
3819
                BLI_memarena_free(smearArena);
 
3820
        }
 
3821
        
 
3822
        return NULL;
 
3823
}
 
3824
 
 
3825
static int project_paint_op(void *state, ImBuf *ibufb, float *lastpos, float *pos)
 
3826
{
 
3827
        /* First unpack args from the struct */
 
3828
        ProjPaintState *ps = (ProjPaintState *)state;
 
3829
        int touch_any = 0;      
 
3830
        
 
3831
        ProjectHandle handles[BLENDER_MAX_THREADS];
 
3832
        ListBase threads;
 
3833
        int a,i;
 
3834
        
 
3835
        if (!project_bucket_iter_init(ps, pos)) {
 
3836
                return 0;
 
3837
        }
 
3838
        
 
3839
        if (ps->thread_tot > 1)
 
3840
                BLI_init_threads(&threads, do_projectpaint_thread, ps->thread_tot);
 
3841
        
 
3842
        /* get the threads running */
 
3843
        for(a=0; a < ps->thread_tot; a++) {
 
3844
                
 
3845
                /* set defaults in handles */
 
3846
                //memset(&handles[a], 0, sizeof(BakeShade));
 
3847
                
 
3848
                handles[a].ps = ps;
 
3849
                VECCOPY2D(handles[a].mval, pos);
 
3850
                VECCOPY2D(handles[a].prevmval, lastpos);
 
3851
                
 
3852
                /* thread spesific */
 
3853
                handles[a].thread_index = a;
 
3854
                
 
3855
                handles[a].projImages = (ProjPaintImage *)BLI_memarena_alloc(ps->arena_mt[a], ps->image_tot * sizeof(ProjPaintImage));
 
3856
                
 
3857
                memcpy(handles[a].projImages, ps->projImages, ps->image_tot * sizeof(ProjPaintImage));
 
3858
                
 
3859
                /* image bounds */
 
3860
                for (i=0; i< ps->image_tot; i++) {
 
3861
                        handles[a].projImages[i].partRedrawRect = (ImagePaintPartialRedraw *)BLI_memarena_alloc(ps->arena_mt[a], sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
 
3862
                        memcpy(handles[a].projImages[i].partRedrawRect, ps->projImages[i].partRedrawRect, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);                     
 
3863
                }
 
3864
 
 
3865
                if (ps->thread_tot > 1)
 
3866
                        BLI_insert_thread(&threads, &handles[a]);
 
3867
        }
 
3868
        
 
3869
        if (ps->thread_tot > 1) /* wait for everything to be done */
 
3870
                BLI_end_threads(&threads);
 
3871
        else
 
3872
                do_projectpaint_thread(&handles[0]);
 
3873
                
 
3874
        
 
3875
        /* move threaded bounds back into ps->projectPartialRedraws */
 
3876
        for(i=0; i < ps->image_tot; i++) {
 
3877
                int touch = 0;
 
3878
                for(a=0; a < ps->thread_tot; a++) {
 
3879
                        touch |= partial_redraw_array_merge(ps->projImages[i].partRedrawRect, handles[a].projImages[i].partRedrawRect, PROJ_BOUNDBOX_SQUARED);
 
3880
                }
 
3881
                
 
3882
                if (touch) {
 
3883
                        ps->projImages[i].touch = 1;
 
3884
                        touch_any = 1;
 
3885
                }
 
3886
        }
 
3887
        
 
3888
        return touch_any;
 
3889
}
 
3890
 
 
3891
 
 
3892
static int project_paint_sub_stroke(ProjPaintState *ps, BrushPainter *painter, short *prevmval_i, short *mval_i, double time, float pressure)
 
3893
{
 
3894
        
 
3895
        /* Use mouse coords as floats for projection painting */
 
3896
        float pos[2];
 
3897
        
 
3898
        pos[0] = mval_i[0];
 
3899
        pos[1] = mval_i[1];
 
3900
        
 
3901
        // we may want to use this later 
 
3902
        // brush_painter_require_imbuf(painter, ((ibuf->rect_float)? 1: 0), 0, 0);
 
3903
        
 
3904
        if (brush_painter_paint(painter, project_paint_op, pos, time, pressure, ps)) {
 
3905
                return 1;
 
3906
        }
 
3907
        else return 0;
 
3908
}
 
3909
 
 
3910
 
 
3911
static int project_paint_stroke(ProjPaintState *ps, BrushPainter *painter, short *prevmval_i, short *mval_i, double time, int update, float pressure)
 
3912
{
 
3913
        int a, redraw = 0;
 
3914
        
 
3915
        for (a=0; a < ps->image_tot; a++) {
 
3916
                partial_redraw_array_init(ps->projImages[a].partRedrawRect);
 
3917
        }
 
3918
        
 
3919
        redraw |= project_paint_sub_stroke(ps, painter, prevmval_i, mval_i, time, pressure);
 
3920
        
 
3921
        if (update) {
 
3922
                if (project_image_refresh_tagged(ps)) {
 
3923
                        if (redraw) {
 
3924
                                force_draw(0); /* imapaint_redraw just calls this in viewport paint anyway */
 
3925
                                /* imapaint_redraw(0, 1, NULL); */
 
3926
                                /* imapaint_clear_partial_redraw(); */ /* not needed since we use our own array */
 
3927
                        }
 
3928
                }
 
3929
        }
 
3930
        
 
3931
        return redraw;
 
3932
}
 
3933
 
287
3934
void undo_imagepaint_step(int step)
288
3935
{
289
3936
        UndoElem *undo;
333
3980
 
334
3981
static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
335
3982
{
336
 
        ImBuf *tmpibuf;
 
3983
        ImBuf *tmpibuf = NULL;
337
3984
        UndoTile *tile;
338
 
        int srcx= 0, srcy= 0, origx, allocsize;
 
3985
        int srcx= 0, srcy= 0, origx;
339
3986
 
340
3987
        IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
341
3988
 
360
4007
        h = ((y + h - 1) >> IMAPAINT_TILE_BITS);
361
4008
        origx = (x >> IMAPAINT_TILE_BITS);
362
4009
        y = (y >> IMAPAINT_TILE_BITS);
363
 
 
364
 
        tmpibuf= IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32,
365
 
                                IB_rectfloat|IB_rect, 0);
366
4010
        
367
4011
        for (; y <= h; y++) {
368
4012
                for (x=origx; x <= w; x++) {
371
4015
                                        break;
372
4016
 
373
4017
                        if(!tile) {
374
 
                                tile= MEM_callocN(sizeof(UndoTile), "ImaUndoTile");
375
 
                                tile->id= ima->id;
376
 
                                tile->x= x;
377
 
                                tile->y= y;
378
 
 
379
 
                                allocsize= IMAPAINT_TILE_SIZE*IMAPAINT_TILE_SIZE*4;
380
 
                                allocsize *= (ibuf->rect_float)? sizeof(float): sizeof(char);
381
 
                                tile->rect= MEM_mapallocN(allocsize, "ImaUndoRect");
382
 
 
383
 
                                undo_copy_tile(tile, tmpibuf, ibuf, 0);
384
 
                                curundo->undosize += allocsize;
385
 
 
386
 
                                BLI_addtail(&curundo->tiles, tile);
 
4018
                                undo_init_tile(&ima->id, ibuf, &tmpibuf, x, y);
387
4019
                        }
388
4020
                }
389
4021
        }
390
4022
 
391
4023
        ibuf->userflags |= IB_BITMAPDIRTY;
392
 
 
393
 
        IMB_freeImBuf(tmpibuf);
 
4024
        
 
4025
        if (tmpibuf)
 
4026
                IMB_freeImBuf(tmpibuf);
394
4027
}
395
4028
 
396
4029
static void imapaint_image_update(Image *image, ImBuf *ibuf, short texpaint)
397
4030
{
398
4031
        if(ibuf->rect_float)
399
 
                imb_freerectImBuf(ibuf); /* force recreate of char rect */
 
4032
                imb_freerectImBuf(ibuf); /* force recreate of char rect */ /* TODO - should just update a portion from imapaintpartial! */
400
4033
        if(ibuf->mipmap[0])
401
4034
                imb_freemipmapImBuf(ibuf);
402
4035
 
404
4037
        if(texpaint || G.sima->lock) {
405
4038
                int w = imapaintpartial.x2 - imapaintpartial.x1;
406
4039
                int h = imapaintpartial.y2 - imapaintpartial.y1;
 
4040
                // printf("%d, %d, \n", w, h);
407
4041
                GPU_paint_update_image(image, imapaintpartial.x1, imapaintpartial.y1, w, h);
408
4042
        }
409
4043
}
461
4095
        if (ibuf->rect_float) {
462
4096
                float *rrgbf = ibuf->rect_float + (ibuf->x*y + x)*4;
463
4097
 
464
 
                if (set) IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb)
465
 
                else IMAPAINT_FLOAT_RGB_COPY(rgb, rrgbf)
 
4098
                if (set) {
 
4099
                        IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb);
 
4100
                } else {
 
4101
                        IMAPAINT_FLOAT_RGB_COPY(rgb, rrgbf);
 
4102
                }
466
4103
        }
467
4104
        else {
468
4105
                char *rrgb = (char*)ibuf->rect + (ibuf->x*y + x)*4;
469
4106
 
470
 
                if (set) IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb)
471
 
                else IMAPAINT_CHAR_RGB_TO_FLOAT(rgb, rrgb)
 
4107
                if (set) {
 
4108
                        IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb)
 
4109
                } else {
 
4110
                        IMAPAINT_CHAR_RGB_TO_FLOAT(rgb, rrgb)
 
4111
                }
472
4112
        }
473
4113
}
474
4114
 
569
4209
        ipos[1]= (int)(pos[1] - ibufb->y/2);
570
4210
}
571
4211
 
 
4212
/* dosnt run for projection painting
 
4213
 * only the old style painting in the 3d view */
572
4214
static int imapaint_paint_op(void *state, ImBuf *ibufb, float *lastpos, float *pos)
573
4215
{
574
4216
        ImagePaintState *s= ((ImagePaintState*)state);
724
4366
                ) {
725
4367
                        ImBuf *ibuf;
726
4368
                        
727
 
                        newimage = (Image*)((s->me->mtface+newfaceindex)->tpage);
 
4369
                        newimage = (s->me->mtface+newfaceindex)->tpage;
728
4370
                        ibuf= BKE_image_get_ibuf(newimage, G.sima?&G.sima->iuser:NULL);
729
4371
 
730
4372
                        if(ibuf && ibuf->rect)
793
4435
void imagepaint_paint(short mousebutton, short texpaint)
794
4436
{
795
4437
        ImagePaintState s;
 
4438
        ProjPaintState ps;
796
4439
        BrushPainter *painter;
797
4440
        ToolSettings *settings= G.scene->toolsettings;
798
 
        short prevmval[2], mval[2];
 
4441
        short prevmval[2], mval[2], project = 0;
 
4442
        short brush_size_orig; /* not nice hack because 1 size brushes always fail with projection paint */
799
4443
        double time;
800
4444
        float pressure;
801
 
 
 
4445
        int init = 1;
 
4446
        
802
4447
        if(!settings->imapaint.brush)
803
4448
                return;
804
 
 
 
4449
        
 
4450
        if (texpaint) { /* are we painting in the 3D view ? */
 
4451
                if ((settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)==0) {
 
4452
                        project= 1;
 
4453
                }
 
4454
        }
 
4455
        
 
4456
        if (G.qual & LR_CTRLKEY) {
 
4457
                persp(PERSP_VIEW);
 
4458
        project_paint_setCursor();
 
4459
                persp(PERSP_WIN);
 
4460
                return;
 
4461
        }
 
4462
        
805
4463
        /* initialize state */
806
4464
        memset(&s, 0, sizeof(s));
 
4465
        memset(&ps, 0, sizeof(ps));
 
4466
        
807
4467
        s.brush = settings->imapaint.brush;
808
4468
        s.tool = settings->imapaint.tool;
809
 
        if(texpaint && (s.tool == PAINT_TOOL_CLONE))
 
4469
        if(texpaint && (project==0) && (s.tool == PAINT_TOOL_CLONE))
810
4470
                s.tool = PAINT_TOOL_DRAW;
811
4471
        s.blend = s.brush->blend;
812
 
 
 
4472
        
 
4473
        if (project) {
 
4474
                ps.brush = s.brush;
 
4475
                ps.tool = s.tool;
 
4476
                ps.blend = s.blend;
 
4477
                
 
4478
                brush_size_orig = ps.brush->size; /* hack, fixme */
 
4479
        }
 
4480
        
813
4481
        if(texpaint) {
814
 
                s.ob = OBACT;
 
4482
                ps.ob = s.ob = OBACT;
815
4483
                if (!s.ob || !(s.ob->lay & G.vd->lay)) return;
816
4484
                s.me = get_mesh(s.ob);
817
4485
                if (!s.me) return;
818
4486
 
819
 
                persp(PERSP_VIEW);
 
4487
                persp(PERSP_VIEW); /* set back to PERSP_WIN before returning */
820
4488
        }
821
4489
        else {
822
4490
                s.image = G.sima->image;
829
4497
                        return;
830
4498
                }
831
4499
        }
832
 
 
 
4500
        
 
4501
        getmouseco_areawin(mval); /* make sure this runs before project_paint_begin() */
 
4502
        
 
4503
        /* note, if we have no UVs on the derived mesh, then we must return here */
 
4504
        if (project) {
 
4505
                /* setup projection painting data */
 
4506
                ps.do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? 0 : 1;
 
4507
                ps.do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? 0 : 1;
 
4508
                ps.do_mask_normal = (settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT) ? 0 : 1;;
 
4509
                
 
4510
                if (ps.tool == PAINT_TOOL_CLONE)
 
4511
                        ps.do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE);
 
4512
                
 
4513
                ps.do_layer_mask = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_MASK) ? 1 : 0;
 
4514
                ps.do_layer_mask_inv = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_MASK_INV) ? 1 : 0;
 
4515
                
 
4516
                
 
4517
#ifndef PROJ_DEBUG_NOSEAMBLEED
 
4518
                ps.seam_bleed_px = settings->imapaint.seam_bleed; /* pixel num to bleed */
 
4519
#endif
 
4520
 
 
4521
                if (ps.do_mask_normal) {
 
4522
                        ps.normal_angle_inner = settings->imapaint.normal_angle;
 
4523
                        ps.normal_angle = (ps.normal_angle_inner + 90.0f) * 0.5f;
 
4524
                }
 
4525
                else {
 
4526
                        ps.normal_angle_inner= ps.normal_angle= settings->imapaint.normal_angle;
 
4527
                }
 
4528
 
 
4529
                ps.normal_angle_inner *=        M_PI_2 / 90;
 
4530
                ps.normal_angle *=                      M_PI_2 / 90;
 
4531
                ps.normal_angle_range = ps.normal_angle - ps.normal_angle_inner;
 
4532
                
 
4533
                if (ps.normal_angle_range <= 0.0f)
 
4534
                        ps.do_mask_normal = 0; /* no need to do blending */
 
4535
 
 
4536
                project_paint_begin(&ps, mval);
 
4537
                
 
4538
                if (ps.dm==NULL) {
 
4539
                        persp(PERSP_WIN);
 
4540
                        return;
 
4541
                }
 
4542
                
 
4543
                /* Dont allow brush size below 2 */
 
4544
                if (ps.brush->size<=1)
 
4545
                        ps.brush->size = 2;
 
4546
        }
 
4547
        
833
4548
        settings->imapaint.flag |= IMAGEPAINT_DRAWING;
834
4549
        undo_imagepaint_push_begin("Image Paint");
835
4550
 
836
4551
        /* create painter and paint once */
837
4552
        painter= brush_painter_new(s.brush);
838
4553
 
839
 
        getmouseco_areawin(mval);
840
 
 
841
4554
        pressure = get_pressure();
842
4555
        s.blend = (get_activedevice() == 2)? BRUSH_BLEND_ERASE_ALPHA: s.brush->blend;
843
4556
        
844
4557
        time= PIL_check_seconds_timer();
845
4558
        prevmval[0]= mval[0];
846
4559
        prevmval[1]= mval[1];
847
 
 
 
4560
        
848
4561
        /* special exception here for too high pressure values on first touch in
849
 
           windows for some tablets */
850
 
    if (!((s.brush->flag & (BRUSH_ALPHA_PRESSURE|BRUSH_SIZE_PRESSURE|
 
4562
         windows for some tablets */
 
4563
        if (!((s.brush->flag & (BRUSH_ALPHA_PRESSURE|BRUSH_SIZE_PRESSURE|
851
4564
                BRUSH_SPACING_PRESSURE|BRUSH_RAD_PRESSURE)) && (get_activedevice() != 0) && (pressure >= 0.99f)))
852
 
                imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
853
 
 
 
4565
        {
 
4566
                if (project) {
 
4567
                        project_paint_stroke(&ps, painter, prevmval, mval, time, 1, pressure);
 
4568
                }
 
4569
                else {
 
4570
                        imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
 
4571
                }
 
4572
        }
 
4573
        
854
4574
        /* paint loop */
855
4575
        do {
856
4576
                getmouseco_areawin(mval);
860
4580
                        
861
4581
                time= PIL_check_seconds_timer();
862
4582
 
863
 
                if((mval[0] != prevmval[0]) || (mval[1] != prevmval[1])) {
864
 
                        imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
865
 
                        prevmval[0]= mval[0];
866
 
                        prevmval[1]= mval[1];
867
 
                }
868
 
                else if (s.brush->flag & BRUSH_AIRBRUSH)
869
 
                        imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
870
 
                else
871
 
                        BIF_wait_for_statechange();
 
4583
                if (project) { /* Projection Painting */
 
4584
                        int redraw = 1;
 
4585
                        
 
4586
                        if (((s.brush->flag & BRUSH_AIRBRUSH) || init)  || ((mval[0] != prevmval[0]) || (mval[1] != prevmval[1]))) {
 
4587
                                redraw = project_paint_stroke(&ps, painter, prevmval, mval, time, 1, pressure);
 
4588
                                prevmval[0]= mval[0];
 
4589
                                prevmval[1]= mval[1];
 
4590
                        }
 
4591
                        else {
 
4592
                                BIF_wait_for_statechange();
872
4593
 
 
4594
                                if (redraw==0) {
 
4595
                                        /* Only so the brush outline is redrawn, pitty we need to do this
 
4596
                                         * however it wont run when the mouse is still so not too bad */
 
4597
                                        force_draw(0);
 
4598
                                }
 
4599
                        }
 
4600
                        
 
4601
                        init = 0;
 
4602
                }
 
4603
                else { 
 
4604
                        if((mval[0] != prevmval[0]) || (mval[1] != prevmval[1])) {
 
4605
                                imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
 
4606
                                prevmval[0]= mval[0];
 
4607
                                prevmval[1]= mval[1];
 
4608
                        }
 
4609
                        else if (s.brush->flag & BRUSH_AIRBRUSH)
 
4610
                                imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
 
4611
                        else
 
4612
                                BIF_wait_for_statechange();
 
4613
                }
873
4614
                /* do mouse checking at the end, so don't check twice, and potentially
874
4615
                   miss a short tap */
875
4616
        } while(get_mbut() & mousebutton);
879
4620
        imapaint_canvas_free(&s);
880
4621
        brush_painter_free(painter);
881
4622
 
 
4623
        if (project) {
 
4624
                ps.brush->size = brush_size_orig;
 
4625
                project_paint_end(&ps);
 
4626
        }
 
4627
        
882
4628
        imapaint_redraw(1, texpaint, s.image);
883
4629
        undo_imagepaint_push_end();
884
4630
        
927
4673
                sample_vpaint();
928
4674
}
929
4675
 
 
4676