4 * Functions to paint images in 2D and 3D.
6 * ***** BEGIN GPL LICENSE BLOCK *****
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22 * All rights reserved.
24 * The Original Code is: some of this file.
26 * Contributor(s): Jens Ole Wund (bjornmose), Campbell Barton (ideasman42)
28 * ***** END GPL LICENSE BLOCK *****
31 /** \file blender/editors/sculpt_paint/paint_image.c
41 #include "MEM_guardedalloc.h"
44 #include "BLI_winstuff.h"
47 #include "BLI_blenlib.h"
48 #include "BLI_dynstr.h"
49 #include "BLI_linklist.h"
50 #include "BLI_memarena.h"
51 #include "BLI_threads.h"
52 #include "BLI_utildefines.h"
56 #include "IMB_imbuf.h"
57 #include "IMB_imbuf_types.h"
59 #include "DNA_brush_types.h"
60 #include "DNA_camera_types.h"
61 #include "DNA_mesh_types.h"
62 #include "DNA_meshdata_types.h"
63 #include "DNA_node_types.h"
64 #include "DNA_object_types.h"
65 #include "DNA_scene_types.h"
66 #include "DNA_texture_types.h"
68 #include "BKE_camera.h"
69 #include "BKE_context.h"
70 #include "BKE_depsgraph.h"
71 #include "BKE_DerivedMesh.h"
72 #include "BKE_idprop.h"
73 #include "BKE_brush.h"
74 #include "BKE_image.h"
75 #include "BKE_library.h"
79 #include "BKE_object.h"
80 #include "BKE_paint.h"
81 #include "BKE_report.h"
82 #include "BKE_scene.h"
85 #include "BIF_glutil.h"
87 #include "UI_view2d.h"
90 #include "ED_screen.h"
91 #include "ED_sculpt.h"
92 #include "ED_uvedit.h"
93 #include "ED_view3d.h"
98 #include "RNA_access.h"
99 #include "RNA_define.h"
100 #include "RNA_enum_types.h"
102 #include "GPU_draw.h"
104 #include "paint_intern.h"
106 /* Defines and Structs */
108 #define IMAPAINT_CHAR_TO_FLOAT(c) ((c)/255.0f)
110 #define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { \
111 (c)[0]= FTOCHAR((f)[0]); \
112 (c)[1]= FTOCHAR((f)[1]); \
113 (c)[2]= FTOCHAR((f)[2]); \
115 #define IMAPAINT_FLOAT_RGBA_TO_CHAR(c, f) { \
116 (c)[0]= FTOCHAR((f)[0]); \
117 (c)[1]= FTOCHAR((f)[1]); \
118 (c)[2]= FTOCHAR((f)[2]); \
119 (c)[3]= FTOCHAR((f)[3]); \
121 #define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { \
122 (f)[0]= IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
123 (f)[1]= IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
124 (f)[2]= IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
126 #define IMAPAINT_CHAR_RGBA_TO_FLOAT(f, c) { \
127 (f)[0]= IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
128 (f)[1]= IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
129 (f)[2]= IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
130 (f)[3]= IMAPAINT_CHAR_TO_FLOAT((c)[3]); \
133 #define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b)
135 #define IMAPAINT_TILE_BITS 6
136 #define IMAPAINT_TILE_SIZE (1 << IMAPAINT_TILE_BITS)
137 #define IMAPAINT_TILE_NUMBER(size) (((size)+IMAPAINT_TILE_SIZE-1) >> IMAPAINT_TILE_BITS)
139 static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint);
142 typedef struct ImagePaintState {
153 short clonefreefloat;
154 char *warnpackedfile;
157 /* texture paint only */
164 typedef struct ImagePaintPartialRedraw {
167 } ImagePaintPartialRedraw;
169 typedef struct ImagePaintRegion {
175 /* ProjectionPaint defines */
177 /* approx the number of buckets to have under the brush,
178 * used with the brush size to set the ps->buckets_x and ps->buckets_y value.
180 * When 3 - a brush should have ~9 buckets under it at once
181 * ...this helps for threading while painting as well as
182 * avoiding initializing pixels that wont touch the brush */
183 #define PROJ_BUCKET_BRUSH_DIV 4
185 #define PROJ_BUCKET_RECT_MIN 4
186 #define PROJ_BUCKET_RECT_MAX 256
188 #define PROJ_BOUNDBOX_DIV 8
189 #define PROJ_BOUNDBOX_SQUARED (PROJ_BOUNDBOX_DIV * PROJ_BOUNDBOX_DIV)
191 //#define PROJ_DEBUG_PAINT 1
192 //#define PROJ_DEBUG_NOSEAMBLEED 1
193 //#define PROJ_DEBUG_PRINT_CLIP 1
194 #define PROJ_DEBUG_WINCLIP 1
196 /* projectFaceSeamFlags options */
197 //#define PROJ_FACE_IGNORE (1<<0) /* When the face is hidden, backfacing or occluded */
198 //#define PROJ_FACE_INIT (1<<1) /* When we have initialized the faces data */
199 #define PROJ_FACE_SEAM1 (1<<0) /* If this face has a seam on any of its edges */
200 #define PROJ_FACE_SEAM2 (1<<1)
201 #define PROJ_FACE_SEAM3 (1<<2)
202 #define PROJ_FACE_SEAM4 (1<<3)
204 #define PROJ_FACE_NOSEAM1 (1<<4)
205 #define PROJ_FACE_NOSEAM2 (1<<5)
206 #define PROJ_FACE_NOSEAM3 (1<<6)
207 #define PROJ_FACE_NOSEAM4 (1<<7)
209 #define PROJ_SRC_VIEW 1
210 #define PROJ_SRC_IMAGE_CAM 2
211 #define PROJ_SRC_IMAGE_VIEW 3
213 #define PROJ_VIEW_DATA_ID "view_data"
214 #define PROJ_VIEW_DATA_SIZE (4*4 + 4*4 + 3) /* viewmat + winmat + clipsta + clipend + is_ortho */
217 /* a slightly scaled down face is used to get fake 3D location for edge pixels in the seams
218 * as this number approaches 1.0f the likelihood increases of float precision errors where
219 * it is occluded by an adjacent face */
220 #define PROJ_FACE_SCALE_SEAM 0.99f
222 #define PROJ_BUCKET_NULL 0
223 #define PROJ_BUCKET_INIT (1<<0)
224 // #define PROJ_BUCKET_CLONE_INIT (1<<1)
226 /* used for testing doubles, if a point is on a line etc */
227 #define PROJ_GEOM_TOLERANCE 0.00075f
230 #define PROJ_VERT_CULL 1
232 #define PI_80_DEG ((M_PI_2 / 9) * 8)
234 /* This is mainly a convenience struct used so we can keep an array of images we use
235 * Thir imbufs, etc, in 1 array, When using threads this array is copied for each thread
236 * because 'partRedrawRect' and 'touch' values would not be thread safe */
237 typedef struct ProjPaintImage {
240 ImagePaintPartialRedraw *partRedrawRect;
241 void **undoRect; /* only used to build undo tiles after painting */
245 /* Main projection painting struct passed to all projection painting functions */
246 typedef struct ProjPaintState {
251 int source; /* PROJ_SRC_**** */
256 /* end similarities with ImagePaintState */
266 MTFace *dm_mtface_clone; /* other UV layer, use for cloning between layers */
267 MTFace *dm_mtface_stencil;
269 /* projection painting only */
270 MemArena *arena_mt[BLENDER_MAX_THREADS];/* for multithreading, the first item is sometimes used for non threaded cases too */
271 LinkNode **bucketRect; /* screen sized 2D array, each pixel has a linked list of ProjPixel's */
272 LinkNode **bucketFaces; /* bucketRect aligned array linkList of faces overlapping each bucket */
273 unsigned char *bucketFlags; /* store if the bucks have been initialized */
274 #ifndef PROJ_DEBUG_NOSEAMBLEED
275 char *faceSeamFlags; /* store info about faces, if they are initialized etc*/
276 float (*faceSeamUVs)[4][2]; /* expanded UVs for faces to use as seams */
277 LinkNode **vertFaces; /* Only needed for when seam_bleed_px is enabled, use to find UV seams */
279 char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */
280 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 */
283 ProjPaintImage *projImages;
285 int image_tot; /* size of projectImages array */
287 float (*screenCoords)[4]; /* verts projected into floating point screen space */
289 float screenMin[2]; /* 2D bounds for mesh verts on the screen's plane (screenspace) */
291 float screen_width; /* Calculated from screenMin & screenMax */
293 int winx, winy; /* from the carea or from the projection render */
295 /* options for projection painting */
297 int do_layer_stencil;
298 int do_layer_stencil_inv;
300 short do_occlude; /* Use raytraced occlusion? - ortherwise will paint right through to the back*/
301 short do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
302 short do_mask_normal; /* mask out pixels based on their normals */
303 float normal_angle; /* what angle to mask at*/
304 float normal_angle_inner;
305 float normal_angle_range; /* difference between normal_angle and normal_angle_inner, for easy access */
308 short is_airbrush; /* only to avoid using (ps.brush->flag & BRUSH_AIRBRUSH) */
309 short is_texbrush; /* only to avoid running */
310 #ifndef PROJ_DEBUG_NOSEAMBLEED
314 float cloneOffset[2];
316 float projectMat[4][4]; /* Projection matrix, use for getting screen coords */
317 float viewDir[3]; /* View vector, use for do_backfacecull and for ray casting with an ortho viewport */
318 float viewPos[3]; /* View location in object relative 3D space, so can compare to verts */
319 float clipsta, clipend;
322 Image *reproject_image;
323 ImBuf *reproject_ibuf;
330 int context_bucket_x, context_bucket_y; /* must lock threads while accessing these */
333 typedef union pixelPointer
335 float *f_pt; /* float buffer */
336 unsigned int *uint_pt; /* 2 ways to access a char buffer */
337 unsigned char *ch_pt;
340 typedef union pixelStore
347 typedef struct ProjPixel {
348 float projCoSS[2]; /* the floating point screen projection of this pixel */
350 /* Only used when the airbrush is disabled.
351 * Store the max mask value to avoid painting over an area with a lower opacity
352 * with an advantage that we can avoid touching the pixel at all, if the
353 * new mask value is lower then mask_max */
354 unsigned short mask_max;
356 /* for various reasons we may want to mask out painting onto this pixel */
361 PixelStore origColor;
365 short image_index; /* if anyone wants to paint onto more then 32768 images they can bite me */
366 unsigned char bb_cell_index;
369 typedef struct ProjPixelClone {
370 struct ProjPixel __pp;
374 /* Finish projection painting structs */
376 typedef struct UndoImageTile {
377 struct UndoImageTile *next, *prev;
379 char idname[MAX_ID_NAME]; /* name instead of pointer*/
380 char ibufname[IB_FILENAME_SIZE];
389 static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0};
393 static void undo_copy_tile(UndoImageTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, int restore)
395 /* copy or swap contents of tile->rect and region in ibuf->rect */
396 IMB_rectcpy(tmpibuf, ibuf, 0, 0, tile->x*IMAPAINT_TILE_SIZE,
397 tile->y*IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
399 if(ibuf->rect_float) {
400 SWAP(void*, tmpibuf->rect_float, tile->rect);
402 SWAP(void*, tmpibuf->rect, tile->rect);
406 IMB_rectcpy(ibuf, tmpibuf, tile->x*IMAPAINT_TILE_SIZE,
407 tile->y*IMAPAINT_TILE_SIZE, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
410 static void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile)
412 ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_IMAGE);
416 for(tile=lb->first; tile; tile=tile->next)
417 if(tile->x == x_tile && tile->y == y_tile && ima->gen_type == tile->gen_type && ima->source == tile->source)
418 if(strcmp(tile->idname, ima->id.name)==0 && strcmp(tile->ibufname, ibuf->name)==0)
422 *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat|IB_rect);
424 tile= MEM_callocN(sizeof(UndoImageTile), "UndoImageTile");
425 BLI_strncpy(tile->idname, ima->id.name, sizeof(tile->idname));
429 allocsize= IMAPAINT_TILE_SIZE*IMAPAINT_TILE_SIZE*4;
430 allocsize *= (ibuf->rect_float)? sizeof(float): sizeof(char);
431 tile->rect= MEM_mapallocN(allocsize, "UndeImageTile.rect");
433 BLI_strncpy(tile->ibufname, ibuf->name, sizeof(tile->ibufname));
435 tile->gen_type= ima->gen_type;
436 tile->source= ima->source;
438 undo_copy_tile(tile, *tmpibuf, ibuf, 0);
439 undo_paint_push_count_alloc(UNDO_PAINT_IMAGE, allocsize);
441 BLI_addtail(lb, tile);
446 static void image_undo_restore(bContext *C, ListBase *lb)
448 Main *bmain= CTX_data_main(C);
450 ImBuf *ibuf, *tmpibuf;
453 tmpibuf= IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32,
454 IB_rectfloat|IB_rect);
456 for(tile=lb->first; tile; tile=tile->next) {
457 /* find image based on name, pointer becomes invalid with global undo */
458 if(ima && strcmp(tile->idname, ima->id.name)==0) {
462 ima= BLI_findstring(&bmain->image, tile->idname, offsetof(ID, name));
465 ibuf= BKE_image_get_ibuf(ima, NULL);
467 if(ima && ibuf && strcmp(tile->ibufname, ibuf->name)!=0) {
468 /* current ImBuf filename was changed, probably current frame
469 was changed when paiting on image sequence, rather than storing
470 full image user (which isn't so obvious, btw) try to find ImBuf with
471 matched file name in list of already loaded images */
473 ibuf= BLI_findstring(&ima->ibufs, tile->ibufname, offsetof(ImBuf, name));
476 if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
479 if (ima->gen_type != tile->gen_type || ima->source != tile->source)
482 undo_copy_tile(tile, tmpibuf, ibuf, 1);
484 GPU_free_image(ima); /* force OpenGL reload */
486 ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
488 ibuf->userflags |= IB_MIPMAP_INVALID; /* force mipmap recreatiom */
492 IMB_freeImBuf(tmpibuf);
495 static void image_undo_free(ListBase *lb)
499 for(tile=lb->first; tile; tile=tile->next)
500 MEM_freeN(tile->rect);
503 /* get active image for face depending on old/new shading system */
505 static Image *imapaint_face_image(const ImagePaintState *s, int face_index)
509 if(scene_use_new_shading_nodes(s->scene)) {
510 MFace *mf = s->me->mface+face_index;
511 ED_object_get_active_image(s->ob, mf->mat_nr, &ima, NULL, NULL);
514 MTFace *tf = s->me->mtface+face_index;
521 static Image *project_paint_face_image(const ProjPaintState *ps, int face_index)
525 if(scene_use_new_shading_nodes(ps->scene)) {
526 MFace *mf = ps->dm_mface+face_index;
527 ED_object_get_active_image(ps->ob, mf->mat_nr, &ima, NULL, NULL);
530 MTFace *tf = ps->dm_mtface+face_index;
537 /* fast projection bucket array lookup, use the safe version for bound checking */
538 static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2])
540 /* If we were not dealing with screenspace 2D coords we could simple do...
541 * ps->bucketRect[x + (y*ps->buckets_y)] */
544 * projCoSS[0] - ps->screenMin[0] : zero origin
545 * ... / ps->screen_width : range from 0.0 to 1.0
546 * ... * ps->buckets_x : use as a bucket index
548 * Second multiplication does similar but for vertical offset
550 return ( (int)(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x)) +
551 ( ( (int)(((projCoSS[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y)) * ps->buckets_x);
554 static int project_bucket_offset_safe(const ProjPaintState *ps, const float projCoSS[2])
556 int bucket_index = project_bucket_offset(ps, projCoSS);
558 if (bucket_index < 0 || bucket_index >= ps->buckets_x*ps->buckets_y) {
566 /* still use 2D X,Y space but this works for verts transformed by a perspective matrix, using their 4th component as a weight */
567 static void barycentric_weights_v2_persp(float v1[4], float v2[4], float v3[4], float co[2], float w[3])
569 float wtot_inv, wtot;
571 w[0] = area_tri_signed_v2(v2, v3, co) / v1[3];
572 w[1] = area_tri_signed_v2(v3, v1, co) / v2[3];
573 w[2] = area_tri_signed_v2(v1, v2, co) / v3[3];
574 wtot = w[0]+w[1]+w[2];
577 wtot_inv = 1.0f/wtot;
579 w[0] = w[0]*wtot_inv;
580 w[1] = w[1]*wtot_inv;
581 w[2] = w[2]*wtot_inv;
583 else /* dummy values for zero area face */
584 w[0] = w[1] = w[2] = 1.0f/3.0f;
587 static float VecZDepthOrtho(float pt[2], float v1[3], float v2[3], float v3[3], float w[3])
589 barycentric_weights_v2(v1, v2, v3, pt, w);
590 return (v1[2]*w[0]) + (v2[2]*w[1]) + (v3[2]*w[2]);
593 static float VecZDepthPersp(float pt[2], float v1[4], float v2[4], float v3[4], float w[3])
595 float wtot_inv, wtot;
598 barycentric_weights_v2_persp(v1, v2, v3, pt, w);
599 /* for the depth we need the weights to match what
600 * barycentric_weights_v2 would return, in this case its easiest just to
601 * undo the 4th axis division and make it unit-sum
603 * don't call barycentric_weights_v2() becaue our callers expect 'w'
604 * to be weighted from the perspective */
605 w_tmp[0]= w[0] * v1[3];
606 w_tmp[1]= w[1] * v2[3];
607 w_tmp[2]= w[2] * v3[3];
609 wtot = w_tmp[0]+w_tmp[1]+w_tmp[2];
612 wtot_inv = 1.0f/wtot;
614 w_tmp[0] = w_tmp[0]*wtot_inv;
615 w_tmp[1] = w_tmp[1]*wtot_inv;
616 w_tmp[2] = w_tmp[2]*wtot_inv;
618 else /* dummy values for zero area face */
619 w_tmp[0] = w_tmp[1] = w_tmp[2] = 1.0f/3.0f;
620 /* done mimicing barycentric_weights_v2() */
622 return (v1[2]*w_tmp[0]) + (v2[2]*w_tmp[1]) + (v3[2]*w_tmp[2]);
626 /* Return the top-most face index that the screen space coord 'pt' touches (or -1) */
627 static int project_paint_PickFace(const ProjPaintState *ps, float pt[2], float w[3], int *side)
631 float *v1, *v2, *v3, *v4;
635 int best_face_index = -1;
636 float z_depth_best = FLT_MAX, z_depth;
639 bucket_index = project_bucket_offset_safe(ps, pt);
640 if (bucket_index==-1)
645 /* we could return 0 for 1 face buckets, as long as this function assumes
646 * that the point its testing is only every originated from an existing face */
648 for (node= ps->bucketFaces[bucket_index]; node; node= node->next) {
649 face_index = GET_INT_FROM_POINTER(node->link);
650 mf= ps->dm_mface + face_index;
652 v1= ps->screenCoords[mf->v1];
653 v2= ps->screenCoords[mf->v2];
654 v3= ps->screenCoords[mf->v3];
656 if (isect_point_tri_v2(pt, v1, v2, v3)) {
657 if (ps->is_ortho) z_depth= VecZDepthOrtho(pt, v1, v2, v3, w_tmp);
658 else z_depth= VecZDepthPersp(pt, v1, v2, v3, w_tmp);
660 if (z_depth < z_depth_best) {
661 best_face_index = face_index;
663 z_depth_best = z_depth;
664 copy_v3_v3(w, w_tmp);
668 v4= ps->screenCoords[mf->v4];
670 if (isect_point_tri_v2(pt, v1, v3, v4)) {
671 if (ps->is_ortho) z_depth= VecZDepthOrtho(pt, v1, v3, v4, w_tmp);
672 else z_depth= VecZDepthPersp(pt, v1, v3, v4, w_tmp);
674 if (z_depth < z_depth_best) {
675 best_face_index = face_index;
677 z_depth_best = z_depth;
678 copy_v3_v3(w, w_tmp);
685 return best_face_index; /* will be -1 or a valid face */
688 /* Converts a uv coord into a pixel location wrapping if the uv is outside 0-1 range */
689 static void uvco_to_wrapped_pxco(float uv[2], int ibuf_x, int ibuf_y, float *x, float *y)
692 *x = (float)fmodf(uv[0], 1.0f);
693 *y = (float)fmodf(uv[1], 1.0f);
695 if (*x < 0.0f) *x += 1.0f;
696 if (*y < 0.0f) *y += 1.0f;
698 *x = *x * ibuf_x - 0.5f;
699 *y = *y * ibuf_y - 0.5f;
702 /* Set the top-most face color that the screen space coord 'pt' touches (or return 0 if none touch) */
703 static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float *rgba_fp, unsigned char *rgba, const int interp)
714 face_index = project_paint_PickFace(ps, pt, w, &side);
716 if (face_index == -1)
719 tf = ps->dm_mtface + face_index;
722 interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[1], tf->uv[2], w);
725 interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
728 ima = project_paint_face_image(ps, face_index);
729 ibuf = ima->ibufs.first; /* we must have got the imbuf before getting here */
734 uvco_to_wrapped_pxco(uv, ibuf->x, ibuf->y, &x, &y);
736 if (ibuf->rect_float) {
738 bilinear_interpolation_color_wrap(ibuf, NULL, rgba_fp, x, y);
742 bilinear_interpolation_color_wrap(ibuf, NULL, rgba_tmp_f, x, y);
743 IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_f);
748 bilinear_interpolation_color_wrap(ibuf, rgba, NULL, x, y);
751 unsigned char rgba_tmp[4];
752 bilinear_interpolation_color_wrap(ibuf, rgba_tmp, NULL, x, y);
753 IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, rgba_tmp);
758 //xi = (int)((uv[0]*ibuf->x) + 0.5f);
759 //yi = (int)((uv[1]*ibuf->y) + 0.5f);
760 //if (xi<0 || xi>=ibuf->x || yi<0 || yi>=ibuf->y) return 0;
763 xi = ((int)(uv[0]*ibuf->x)) % ibuf->x;
764 if (xi<0) xi += ibuf->x;
765 yi = ((int)(uv[1]*ibuf->y)) % ibuf->y;
766 if (yi<0) yi += ibuf->y;
770 if (ibuf->rect_float) {
771 float *rgba_tmp_fp = ibuf->rect_float + (xi + yi * ibuf->x * 4);
772 IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_fp);
775 *((unsigned int *)rgba) = *(unsigned int *)(((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4));
780 if (ibuf->rect_float) {
781 copy_v4_v4(rgba_fp, ((float *)ibuf->rect_float + ((xi + yi * ibuf->x) * 4)));
784 char *tmp_ch= ((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4);
785 IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, tmp_ch);
792 /* Check if 'pt' is infront of the 3 verts on the Z axis (used for screenspace occlusuion test)
795 * -1 : no occlusion but 2D intersection is true (avoid testing the other half of a quad)
797 2 : occluded with w[3] weights set (need to know in some cases) */
799 static int project_paint_occlude_ptv(float pt[3], float v1[4], float v2[4], float v3[4], float w[3], int is_ortho)
801 /* if all are behind us, return false */
802 if(v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2])
805 /* do a 2D point in try intersection */
806 if (!isect_point_tri_v2(pt, v1, v2, v3))
807 return 0; /* we know there is */
810 /* From here on we know there IS an intersection */
811 /* if ALL of the verts are infront of us then we know it intersects ? */
812 if(v1[2] < pt[2] && v2[2] < pt[2] && v3[2] < pt[2]) {
816 /* we intersect? - find the exact depth at the point of intersection */
817 /* Is this point is occluded by another face? */
819 if (VecZDepthOrtho(pt, v1, v2, v3, w) < pt[2]) return 2;
822 if (VecZDepthPersp(pt, v1, v2, v3, w) < pt[2]) return 2;
829 static int project_paint_occlude_ptv_clip(
830 const ProjPaintState *ps, const MFace *mf,
831 float pt[3], float v1[4], float v2[4], float v3[4],
835 int ret = project_paint_occlude_ptv(pt, v1, v2, v3, w, ps->is_ortho);
840 if (ret==1) { /* weights not calculated */
841 if (ps->is_ortho) barycentric_weights_v2(v1, v2, v3, pt, w);
842 else barycentric_weights_v2_persp(v1, v2, v3, pt, w);
845 /* Test if we're in the clipped area, */
846 if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
847 else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
849 if(!ED_view3d_test_clipping(ps->rv3d, wco, 1)) {
857 /* Check if a screenspace location is occluded by any other faces
858 * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison
859 * and dosn't need to be correct in relation to X and Y coords (this is the case in perspective view) */
860 static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *bucketFace, const int orig_face, float pixelScreenCo[4])
865 float w[3]; /* not needed when clipping */
866 const short do_clip= ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
868 /* we could return 0 for 1 face buckets, as long as this function assumes
869 * that the point its testing is only every originated from an existing face */
871 for (; bucketFace; bucketFace = bucketFace->next) {
872 face_index = GET_INT_FROM_POINTER(bucketFace->link);
874 if (orig_face != face_index) {
875 mf = ps->dm_mface + face_index;
877 isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], 0);
879 isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], w, ps->is_ortho);
881 /* Note, if isect_ret==-1 then we dont want to test the other side of the quad */
882 if (isect_ret==0 && mf->v4) {
884 isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], 1);
886 isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], w, ps->is_ortho);
889 /* TODO - we may want to cache the first hit,
890 * it is not possible to swap the face order in the list anymore */
898 /* basic line intersection, could move to math_geom.c, 2 points with a horiz line
899 * 1 for an intersection, 2 if the first point is aligned, 3 if the second point is aligned */
901 #define ISECT_TRUE_P1 2
902 #define ISECT_TRUE_P2 3
903 static int line_isect_y(const float p1[2], const float p2[2], const float y_level, float *x_isect)
907 if (y_level==p1[1]) { /* are we touching the first point? - no interpolation needed */
909 return ISECT_TRUE_P1;
911 if (y_level==p2[1]) { /* are we touching the second point? - no interpolation needed */
913 return ISECT_TRUE_P2;
916 y_diff= fabsf(p1[1]-p2[1]); /* yuck, horizontal line, we cant do much here */
918 if (y_diff < 0.000001f) {
919 *x_isect = (p1[0]+p2[0]) * 0.5f;
923 if (p1[1] > y_level && p2[1] < y_level) {
924 *x_isect = (p2[0]*(p1[1]-y_level) + p1[0]*(y_level-p2[1])) / y_diff; /*(p1[1]-p2[1]);*/
927 else if (p1[1] < y_level && p2[1] > y_level) {
928 *x_isect = (p2[0]*(y_level-p1[1]) + p1[0]*(p2[1]-y_level)) / y_diff; /*(p2[1]-p1[1]);*/
936 static int line_isect_x(const float p1[2], const float p2[2], const float x_level, float *y_isect)
940 if (x_level==p1[0]) { /* are we touching the first point? - no interpolation needed */
942 return ISECT_TRUE_P1;
944 if (x_level==p2[0]) { /* are we touching the second point? - no interpolation needed */
946 return ISECT_TRUE_P2;
949 x_diff= fabsf(p1[0]-p2[0]); /* yuck, horizontal line, we cant do much here */
951 if (x_diff < 0.000001f) { /* yuck, vertical line, we cant do much here */
952 *y_isect = (p1[0]+p2[0]) * 0.5f;
956 if (p1[0] > x_level && p2[0] < x_level) {
957 *y_isect = (p2[1]*(p1[0]-x_level) + p1[1]*(x_level-p2[0])) / x_diff; /*(p1[0]-p2[0]);*/
960 else if (p1[0] < x_level && p2[0] > x_level) {
961 *y_isect = (p2[1]*(x_level-p1[0]) + p1[1]*(p2[0]-x_level)) / x_diff; /*(p2[0]-p1[0]);*/
969 /* simple func use for comparing UV locations to check if there are seams.
970 * Its possible this gives incorrect results, when the UVs for 1 face go into the next
971 * tile, but do not do this for the adjacent face, it could return a false positive.
972 * This is so unlikely that Id not worry about it. */
973 #ifndef PROJ_DEBUG_NOSEAMBLEED
974 static int cmp_uv(const float vec2a[2], const float vec2b[2])
976 /* if the UV's are not between 0.0 and 1.0 */
977 float xa = (float)fmodf(vec2a[0], 1.0f);
978 float ya = (float)fmodf(vec2a[1], 1.0f);
980 float xb = (float)fmodf(vec2b[0], 1.0f);
981 float yb = (float)fmodf(vec2b[1], 1.0f);
983 if (xa < 0.0f) xa += 1.0f;
984 if (ya < 0.0f) ya += 1.0f;
986 if (xb < 0.0f) xb += 1.0f;
987 if (yb < 0.0f) yb += 1.0f;
989 return ((fabsf(xa-xb) < PROJ_GEOM_TOLERANCE) && (fabsf(ya-yb) < PROJ_GEOM_TOLERANCE)) ? 1:0;
993 /* set min_px and max_px to the image space bounds of the UV coords
994 * return zero if there is no area in the returned rectangle */
995 #ifndef PROJ_DEBUG_NOSEAMBLEED
996 static int pixel_bounds_uv(
997 const float uv1[2], const float uv2[2], const float uv3[2], const float uv4[2],
999 const int ibuf_x, const int ibuf_y,
1002 float min_uv[2], max_uv[2]; /* UV bounds */
1004 INIT_MINMAX2(min_uv, max_uv);
1006 DO_MINMAX2(uv1, min_uv, max_uv);
1007 DO_MINMAX2(uv2, min_uv, max_uv);
1008 DO_MINMAX2(uv3, min_uv, max_uv);
1010 DO_MINMAX2(uv4, min_uv, max_uv);
1012 bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
1013 bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
1015 bounds_px->xmax = (int)(ibuf_x * max_uv[0]) +1;
1016 bounds_px->ymax = (int)(ibuf_y * max_uv[1]) +1;
1018 /*printf("%d %d %d %d \n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
1020 /* face uses no UV area when quantized to pixels? */
1021 return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
1025 static int pixel_bounds_array(float (* uv)[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, int tot)
1027 float min_uv[2], max_uv[2]; /* UV bounds */
1033 INIT_MINMAX2(min_uv, max_uv);
1036 DO_MINMAX2((*uv), min_uv, max_uv);
1040 bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
1041 bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
1043 bounds_px->xmax = (int)(ibuf_x * max_uv[0]) +1;
1044 bounds_px->ymax = (int)(ibuf_y * max_uv[1]) +1;
1046 /*printf("%d %d %d %d \n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
1048 /* face uses no UV area when quantized to pixels? */
1049 return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
1052 #ifndef PROJ_DEBUG_NOSEAMBLEED
1054 /* This function returns 1 if this face has a seam along the 2 face-vert indices
1055 * 'orig_i1_fidx' and 'orig_i2_fidx' */
1056 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)
1060 unsigned int i1, i2;
1061 int i1_fidx = -1, i2_fidx = -1; /* index in face */
1064 const MFace *orig_mf = ps->dm_mface + orig_face;
1065 const MTFace *orig_tf = ps->dm_mtface + orig_face;
1067 /* vert indices from face vert order indices */
1068 i1 = (*(&orig_mf->v1 + orig_i1_fidx));
1069 i2 = (*(&orig_mf->v1 + orig_i2_fidx));
1071 for (node = ps->vertFaces[i1]; node; node = node->next) {
1072 face_index = GET_INT_FROM_POINTER(node->link);
1074 if (face_index != orig_face) {
1075 mf = ps->dm_mface + face_index;
1076 /* could check if the 2 faces images match here,
1077 * but then there wouldn't be a way to return the opposite face's info */
1080 /* We need to know the order of the verts in the adjacent face
1081 * set the i1_fidx and i2_fidx to (0,1,2,3) */
1082 if (mf->v1==i1) i1_fidx = 0;
1083 else if (mf->v2==i1) i1_fidx = 1;
1084 else if (mf->v3==i1) i1_fidx = 2;
1085 else if (mf->v4 && mf->v4==i1) i1_fidx = 3;
1087 if (mf->v1==i2) i2_fidx = 0;
1088 else if (mf->v2==i2) i2_fidx = 1;
1089 else if (mf->v3==i2) i2_fidx = 2;
1090 else if (mf->v4 && mf->v4==i2) i2_fidx = 3;
1092 /* Only need to check if 'i2_fidx' is valid because we know i1_fidx is the same vert on both faces */
1093 if (i2_fidx != -1) {
1094 Image *tpage = project_paint_face_image(ps, face_index);
1095 Image *orig_tpage = project_paint_face_image(ps, orig_face);
1097 /* This IS an adjacent face!, now lets check if the UVs are ok */
1098 tf = ps->dm_mtface + face_index;
1100 /* set up the other face */
1101 *other_face = face_index;
1102 *orig_fidx = (i1_fidx < i2_fidx) ? i1_fidx : i2_fidx;
1104 /* first test if they have the same image */
1105 if ( (orig_tpage == tpage) &&
1106 cmp_uv(orig_tf->uv[orig_i1_fidx], tf->uv[i1_fidx]) &&
1107 cmp_uv(orig_tf->uv[orig_i2_fidx], tf->uv[i2_fidx]) )
1109 // printf("SEAM (NONE)\n");
1114 // printf("SEAM (UV GAP)\n");
1120 // printf("SEAM (NO FACE)\n");
1125 /* Calculate outset UV's, this is not the same as simply scaling the UVs,
1126 * since the outset coords are a margin that keep an even distance from the original UV's,
1127 * note that the image aspect is taken into account */
1128 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)
1130 float a1, a2, a3, a4=0.0f;
1131 float puv[4][2]; /* pixelspace uv's */
1132 float no1[2], no2[2], no3[2], no4[2]; /* normals */
1133 float dir1[2], dir2[2], dir3[2], dir4[2];
1136 ibuf_inv[0]= 1.0f / (float)ibuf_x;
1137 ibuf_inv[1]= 1.0f / (float)ibuf_y;
1139 /* make UV's in pixel space so we can */
1140 puv[0][0] = orig_uv[0][0] * ibuf_x;
1141 puv[0][1] = orig_uv[0][1] * ibuf_y;
1143 puv[1][0] = orig_uv[1][0] * ibuf_x;
1144 puv[1][1] = orig_uv[1][1] * ibuf_y;
1146 puv[2][0] = orig_uv[2][0] * ibuf_x;
1147 puv[2][1] = orig_uv[2][1] * ibuf_y;
1150 puv[3][0] = orig_uv[3][0] * ibuf_x;
1151 puv[3][1] = orig_uv[3][1] * ibuf_y;
1154 /* face edge directions */
1155 sub_v2_v2v2(dir1, puv[1], puv[0]);
1156 sub_v2_v2v2(dir2, puv[2], puv[1]);
1161 sub_v2_v2v2(dir3, puv[3], puv[2]);
1162 sub_v2_v2v2(dir4, puv[0], puv[3]);
1167 sub_v2_v2v2(dir3, puv[0], puv[2]);
1171 /* TODO - angle_normalized_v2v2(...) * (M_PI/180.0f)
1172 * This is incorrect. Its already given radians but without it wont work.
1173 * need to look into a fix - campbell */
1175 a1 = shell_angle_to_dist(angle_normalized_v2v2(dir4, dir1) * ((float)M_PI/180.0f));
1176 a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI/180.0f));
1177 a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI/180.0f));
1178 a4 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir4) * ((float)M_PI/180.0f));
1181 a1 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir1) * ((float)M_PI/180.0f));
1182 a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI/180.0f));
1183 a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI/180.0f));
1187 sub_v2_v2v2(no1, dir4, dir1);
1188 sub_v2_v2v2(no2, dir1, dir2);
1189 sub_v2_v2v2(no3, dir2, dir3);
1190 sub_v2_v2v2(no4, dir3, dir4);
1195 mul_v2_fl(no1, a1*scaler);
1196 mul_v2_fl(no2, a2*scaler);
1197 mul_v2_fl(no3, a3*scaler);
1198 mul_v2_fl(no4, a4*scaler);
1199 add_v2_v2v2(outset_uv[0], puv[0], no1);
1200 add_v2_v2v2(outset_uv[1], puv[1], no2);
1201 add_v2_v2v2(outset_uv[2], puv[2], no3);
1202 add_v2_v2v2(outset_uv[3], puv[3], no4);
1203 mul_v2_v2(outset_uv[0], ibuf_inv);
1204 mul_v2_v2(outset_uv[1], ibuf_inv);
1205 mul_v2_v2(outset_uv[2], ibuf_inv);
1206 mul_v2_v2(outset_uv[3], ibuf_inv);
1209 sub_v2_v2v2(no1, dir3, dir1);
1210 sub_v2_v2v2(no2, dir1, dir2);
1211 sub_v2_v2v2(no3, dir2, dir3);
1215 mul_v2_fl(no1, a1*scaler);
1216 mul_v2_fl(no2, a2*scaler);
1217 mul_v2_fl(no3, a3*scaler);
1218 add_v2_v2v2(outset_uv[0], puv[0], no1);
1219 add_v2_v2v2(outset_uv[1], puv[1], no2);
1220 add_v2_v2v2(outset_uv[2], puv[2], no3);
1222 mul_v2_v2(outset_uv[0], ibuf_inv);
1223 mul_v2_v2(outset_uv[1], ibuf_inv);
1224 mul_v2_v2(outset_uv[2], ibuf_inv);
1229 * Be tricky with flags, first 4 bits are PROJ_FACE_SEAM1 to 4, last 4 bits are PROJ_FACE_NOSEAM1 to 4
1230 * 1<<i - where i is (0-3)
1232 * If we're multithreadng, make sure threads are locked when this is called
1234 static void project_face_seams_init(const ProjPaintState *ps, const int face_index, const int is_quad)
1236 int other_face, other_fidx; /* vars for the other face, we also set its flag */
1237 int fidx1 = is_quad ? 3 : 2;
1238 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 */
1241 if ((ps->faceSeamFlags[face_index] & (1<<fidx1|16<<fidx1)) == 0) {
1242 if (check_seam(ps, face_index, fidx1, fidx2, &other_face, &other_fidx)) {
1243 ps->faceSeamFlags[face_index] |= 1<<fidx1;
1244 if (other_face != -1)
1245 ps->faceSeamFlags[other_face] |= 1<<other_fidx;
1248 ps->faceSeamFlags[face_index] |= 16<<fidx1;
1249 if (other_face != -1)
1250 ps->faceSeamFlags[other_face] |= 16<<other_fidx; /* second 4 bits for disabled */
1257 #endif // PROJ_DEBUG_NOSEAMBLEED
1260 /* Converts a UV location to a 3D screenspace location
1261 * Takes a 'uv' and 3 UV coords, and sets the values of pixelScreenCo
1263 * This is used for finding a pixels location in screenspace for painting */
1264 static void screen_px_from_ortho(
1266 float v1co[3], float v2co[3], float v3co[3], /* Screenspace coords */
1267 float uv1co[2], float uv2co[2], float uv3co[2],
1268 float pixelScreenCo[4],
1271 barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
1272 interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
1275 /* same as screen_px_from_ortho except we need to take into account
1276 * the perspective W coord for each vert */
1277 static void screen_px_from_persp(
1279 float v1co[4], float v2co[4], float v3co[4], /* screenspace coords */
1280 float uv1co[2], float uv2co[2], float uv3co[2],
1281 float pixelScreenCo[4],
1285 float wtot_inv, wtot;
1286 barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
1288 /* re-weight from the 4th coord of each screen vert */
1293 wtot = w[0]+w[1]+w[2];
1296 wtot_inv = 1.0f / wtot;
1302 w[0] = w[1] = w[2] = 1.0f/3.0f; /* dummy values for zero area face */
1304 /* done re-weighting */
1306 interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
1309 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])
1311 float *uvCo1, *uvCo2, *uvCo3;
1312 float uv_other[2], x, y;
1314 uvCo1 = (float *)tf_other->uv[0];
1316 uvCo2 = (float *)tf_other->uv[2];
1317 uvCo3 = (float *)tf_other->uv[3];
1320 uvCo2 = (float *)tf_other->uv[1];
1321 uvCo3 = (float *)tf_other->uv[2];
1324 interp_v2_v2v2v2(uv_other, uvCo1, uvCo2, uvCo3, (float*)w);
1327 uvco_to_wrapped_pxco(uv_other, ibuf_other->x, ibuf_other->y, &x, &y);
1330 if (ibuf_other->rect_float) { /* from float to float */
1331 bilinear_interpolation_color_wrap(ibuf_other, NULL, rgba_f, x, y);
1333 else { /* from char to float */
1334 bilinear_interpolation_color_wrap(ibuf_other, rgba_ub, NULL, x, y);
1339 /* run this outside project_paint_uvpixel_init since pixels with mask 0 dont need init */
1340 static float project_paint_uvpixel_mask(
1341 const ProjPaintState *ps,
1342 const int face_index,
1349 if (ps->do_layer_stencil) {
1350 /* another UV layers image is masking this one's */
1352 Image *other_tpage = project_paint_face_image(ps, face_index);
1353 const MTFace *tf_other = ps->dm_mtface_stencil + face_index;
1355 if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) {
1356 /* BKE_image_get_ibuf - TODO - this may be slow */
1357 unsigned char rgba_ub[4];
1360 project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, rgba_f);
1362 if (ibuf_other->rect_float) { /* from float to float */
1363 mask = ((rgba_f[0]+rgba_f[1]+rgba_f[2])/3.0f) * rgba_f[3];
1365 else { /* from char to float */
1366 mask = ((rgba_ub[0]+rgba_ub[1]+rgba_ub[2])/(256*3.0f)) * (rgba_ub[3]/256.0f);
1369 if (!ps->do_layer_stencil_inv) /* matching the gimps layer mask black/white rules, white==full opacity */
1370 mask = (1.0f - mask);
1383 /* calculate mask */
1384 if (ps->do_mask_normal) {
1385 MFace *mf = ps->dm_mface + face_index;
1386 short *no1, *no2, *no3;
1388 no1 = ps->dm_mvert[mf->v1].no;
1390 no2 = ps->dm_mvert[mf->v3].no;
1391 no3 = ps->dm_mvert[mf->v4].no;
1394 no2 = ps->dm_mvert[mf->v2].no;
1395 no3 = ps->dm_mvert[mf->v3].no;
1398 no[0] = w[0]*no1[0] + w[1]*no2[0] + w[2]*no3[0];
1399 no[1] = w[0]*no1[1] + w[1]*no2[1] + w[2]*no3[1];
1400 no[2] = w[0]*no1[2] + w[1]*no2[2] + w[2]*no3[2];
1403 /* now we can use the normal as a mask */
1405 angle = angle_normalized_v3v3((float *)ps->viewDir, no);
1408 /* Annoying but for the perspective view we need to get the pixels location in 3D space :/ */
1409 float viewDirPersp[3];
1410 float *co1, *co2, *co3;
1411 co1 = ps->dm_mvert[mf->v1].co;
1413 co2 = ps->dm_mvert[mf->v3].co;
1414 co3 = ps->dm_mvert[mf->v4].co;
1417 co2 = ps->dm_mvert[mf->v2].co;
1418 co3 = ps->dm_mvert[mf->v3].co;
1421 /* Get the direction from the viewPoint to the pixel and normalize */
1422 viewDirPersp[0] = (ps->viewPos[0] - (w[0]*co1[0] + w[1]*co2[0] + w[2]*co3[0]));
1423 viewDirPersp[1] = (ps->viewPos[1] - (w[0]*co1[1] + w[1]*co2[1] + w[2]*co3[1]));
1424 viewDirPersp[2] = (ps->viewPos[2] - (w[0]*co1[2] + w[1]*co2[2] + w[2]*co3[2]));
1425 normalize_v3(viewDirPersp);
1427 angle = angle_normalized_v3v3(viewDirPersp, no);
1430 if (angle >= ps->normal_angle) {
1431 return 0.0f; /* outsize the normal limit*/
1433 else if (angle > ps->normal_angle_inner) {
1434 mask *= (ps->normal_angle - angle) / ps->normal_angle_range;
1435 } /* otherwise no mask normal is needed, were within the limit */
1438 // This only works when the opacity dosnt change while painting, stylus pressure messes with this
1440 // if (ps->is_airbrush==0) mask *= brush_alpha(ps->brush);
1445 /* run this function when we know a bucket's, face's pixel can be initialized,
1446 * return the ProjPixel which is added to 'ps->bucketRect[bucket_index]' */
1447 static ProjPixel *project_paint_uvpixel_init(
1448 const ProjPaintState *ps,
1451 short x_px, short y_px,
1453 const int face_index,
1454 const int image_index,
1455 const float pixelScreenCo[4],
1459 ProjPixel *projPixel;
1462 /* wrap pixel location */
1463 x_px = x_px % ibuf->x;
1464 if (x_px<0) x_px += ibuf->x;
1465 y_px = y_px % ibuf->y;
1466 if (y_px<0) y_px += ibuf->y;
1468 if (ps->tool==PAINT_TOOL_CLONE) {
1469 size = sizeof(ProjPixelClone);
1471 else if (ps->tool==PAINT_TOOL_SMEAR) {
1472 size = sizeof(ProjPixelClone);
1475 size = sizeof(ProjPixel);
1478 projPixel = (ProjPixel *)BLI_memarena_alloc(arena, size);
1479 //memset(projPixel, 0, size);
1481 if (ibuf->rect_float) {
1482 projPixel->pixel.f_pt = (float *)ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4);
1483 projPixel->origColor.f[0] = projPixel->newColor.f[0] = projPixel->pixel.f_pt[0];
1484 projPixel->origColor.f[1] = projPixel->newColor.f[1] = projPixel->pixel.f_pt[1];
1485 projPixel->origColor.f[2] = projPixel->newColor.f[2] = projPixel->pixel.f_pt[2];
1486 projPixel->origColor.f[3] = projPixel->newColor.f[3] = projPixel->pixel.f_pt[3];
1489 projPixel->pixel.ch_pt = ((unsigned char *)ibuf->rect + ((x_px + y_px * ibuf->x) * 4));
1490 projPixel->origColor.uint = projPixel->newColor.uint = *projPixel->pixel.uint_pt;
1493 /* screenspace unclamped, we could keep its z and w values but dont need them at the moment */
1494 copy_v2_v2(projPixel->projCoSS, pixelScreenCo);
1496 projPixel->x_px = x_px;
1497 projPixel->y_px = y_px;
1499 projPixel->mask = (unsigned short)(mask * 65535);
1500 projPixel->mask_max = 0;
1502 /* which bounding box cell are we in?, needed for undo */
1503 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 ;
1505 /* done with view3d_project_float inline */
1506 if (ps->tool==PAINT_TOOL_CLONE) {
1507 if (ps->dm_mtface_clone) {
1509 Image *other_tpage = project_paint_face_image(ps, face_index);
1510 const MTFace *tf_other = ps->dm_mtface_clone + face_index;
1512 if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) {
1513 /* BKE_image_get_ibuf - TODO - this may be slow */
1515 if (ibuf->rect_float) {
1516 if (ibuf_other->rect_float) { /* from float to float */
1517 project_face_pixel(tf_other, ibuf_other, w, side, NULL, ((ProjPixelClone *)projPixel)->clonepx.f);
1519 else { /* from char to float */
1520 unsigned char rgba_ub[4];
1521 project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, NULL);
1522 IMAPAINT_CHAR_RGBA_TO_FLOAT(((ProjPixelClone *)projPixel)->clonepx.f, rgba_ub);
1526 if (ibuf_other->rect_float) { /* float to char */
1528 project_face_pixel(tf_other, ibuf_other, w, side, NULL, rgba);
1529 IMAPAINT_FLOAT_RGBA_TO_CHAR(((ProjPixelClone *)projPixel)->clonepx.ch, rgba)
1531 else { /* char to char */
1532 project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL);
1537 if (ibuf->rect_float) {
1538 ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0;
1541 ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0;
1548 sub_v2_v2v2(co, projPixel->projCoSS, (float *)ps->cloneOffset);
1550 /* no need to initialize the bucket, we're only checking buckets faces and for this
1551 * the faces are already initialized in project_paint_delayed_face_init(...) */
1552 if (ibuf->rect_float) {
1553 if (!project_paint_PickColor(ps, co, ((ProjPixelClone *)projPixel)->clonepx.f, NULL, 1)) {
1554 ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0; /* zero alpha - ignore */
1558 if (!project_paint_PickColor(ps, co, NULL, ((ProjPixelClone *)projPixel)->clonepx.ch, 1)) {
1559 ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0; /* zero alpha - ignore */
1565 #ifdef PROJ_DEBUG_PAINT
1566 if (ibuf->rect_float) projPixel->pixel.f_pt[0] = 0;
1567 else projPixel->pixel.ch_pt[0] = 0;
1569 projPixel->image_index = image_index;
1574 static int line_clip_rect2f(
1576 const float l1[2], const float l2[2],
1577 float l1_clip[2], float l2_clip[2])
1579 /* first account for horizontal, then vertical lines */
1581 if (fabsf(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) {
1582 /* is the line out of range on its Y axis? */
1583 if (l1[1] < rect->ymin || l1[1] > rect->ymax) {
1586 /* line is out of range on its X axis */
1587 if ((l1[0] < rect->xmin && l2[0] < rect->xmin) || (l1[0] > rect->xmax && l2[0] > rect->xmax)) {
1592 if (fabsf(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/
1593 if (BLI_in_rctf(rect, l1[0], l1[1])) {
1594 copy_v2_v2(l1_clip, l1);
1595 copy_v2_v2(l2_clip, l2);
1603 copy_v2_v2(l1_clip, l1);
1604 copy_v2_v2(l2_clip, l2);
1605 CLAMP(l1_clip[0], rect->xmin, rect->xmax);
1606 CLAMP(l2_clip[0], rect->xmin, rect->xmax);
1609 else if (fabsf(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) {
1610 /* is the line out of range on its X axis? */
1611 if (l1[0] < rect->xmin || l1[0] > rect->xmax) {
1615 /* line is out of range on its Y axis */
1616 if ((l1[1] < rect->ymin && l2[1] < rect->ymin) || (l1[1] > rect->ymax && l2[1] > rect->ymax)) {
1620 if (fabsf(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/
1621 if (BLI_in_rctf(rect, l1[0], l1[1])) {
1622 copy_v2_v2(l1_clip, l1);
1623 copy_v2_v2(l2_clip, l2);
1631 copy_v2_v2(l1_clip, l1);
1632 copy_v2_v2(l2_clip, l2);
1633 CLAMP(l1_clip[1], rect->ymin, rect->ymax);
1634 CLAMP(l2_clip[1], rect->ymin, rect->ymax);
1642 /* Done with vertical lines */
1644 /* are either of the points inside the rectangle ? */
1645 if (BLI_in_rctf(rect, l1[0], l1[1])) {
1646 copy_v2_v2(l1_clip, l1);
1650 if (BLI_in_rctf(rect, l2[0], l2[1])) {
1651 copy_v2_v2(l2_clip, l2);
1655 /* line inside rect */
1656 if (ok1 && ok2) return 1;
1659 if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
1660 if (l1[1] < l2[1]) { /* line 1 is outside */
1662 l1_clip[1] = rect->ymin;
1667 l2_clip[1] = rect->ymin;
1672 if (ok1 && ok2) return 1;
1674 if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
1675 if (l1[1] > l2[1]) { /* line 1 is outside */
1677 l1_clip[1] = rect->ymax;
1682 l2_clip[1] = rect->ymax;
1687 if (ok1 && ok2) return 1;
1690 if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
1691 if (l1[0] < l2[0]) { /* line 1 is outside */
1692 l1_clip[0] = rect->xmin;
1697 l2_clip[0] = rect->xmin;
1703 if (ok1 && ok2) return 1;
1705 if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
1706 if (l1[0] > l2[0]) { /* line 1 is outside */
1707 l1_clip[0] = rect->xmax;
1712 l2_clip[0] = rect->xmax;
1729 /* scale the quad & tri about its center
1730 * scaling by PROJ_FACE_SCALE_SEAM (0.99x) is used for getting fake UV pixel coords that are on the
1731 * edge of the face but slightly inside it occlusion tests dont return hits on adjacent faces */
1732 #ifndef PROJ_DEBUG_NOSEAMBLEED
1733 static void scale_quad(float insetCos[4][3], float *origCos[4], const float inset)
1736 cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0] + origCos[3][0]) / 4.0f;
1737 cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1] + origCos[3][1]) / 4.0f;
1738 cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2] + origCos[3][2]) / 4.0f;
1740 sub_v3_v3v3(insetCos[0], origCos[0], cent);
1741 sub_v3_v3v3(insetCos[1], origCos[1], cent);
1742 sub_v3_v3v3(insetCos[2], origCos[2], cent);
1743 sub_v3_v3v3(insetCos[3], origCos[3], cent);
1745 mul_v3_fl(insetCos[0], inset);
1746 mul_v3_fl(insetCos[1], inset);
1747 mul_v3_fl(insetCos[2], inset);
1748 mul_v3_fl(insetCos[3], inset);
1750 add_v3_v3(insetCos[0], cent);
1751 add_v3_v3(insetCos[1], cent);
1752 add_v3_v3(insetCos[2], cent);
1753 add_v3_v3(insetCos[3], cent);
1757 static void scale_tri(float insetCos[4][3], float *origCos[4], const float inset)
1760 cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0]) / 3.0f;
1761 cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1]) / 3.0f;
1762 cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2]) / 3.0f;
1764 sub_v3_v3v3(insetCos[0], origCos[0], cent);
1765 sub_v3_v3v3(insetCos[1], origCos[1], cent);
1766 sub_v3_v3v3(insetCos[2], origCos[2], cent);
1768 mul_v3_fl(insetCos[0], inset);
1769 mul_v3_fl(insetCos[1], inset);
1770 mul_v3_fl(insetCos[2], inset);
1772 add_v3_v3(insetCos[0], cent);
1773 add_v3_v3(insetCos[1], cent);
1774 add_v3_v3(insetCos[2], cent);
1776 #endif //PROJ_DEBUG_NOSEAMBLEED
1778 static float Vec2Lenf_nosqrt(const float *v1, const float *v2)
1787 static float Vec2Lenf_nosqrt_other(const float *v1, const float v2_1, const float v2_2)
1796 /* note, use a squared value so we can use Vec2Lenf_nosqrt
1797 * be sure that you have done a bounds check first or this may fail */
1798 /* only give bucket_bounds as an arg because we need it elsewhere */
1799 static int project_bucket_isect_circle(const float cent[2], const float radius_squared, rctf *bucket_bounds)
1802 /* Would normally to a simple intersection test, however we know the bounds of these 2 already intersect
1803 * so we only need to test if the center is inside the vertical or horizontal bounds on either axis,
1804 * this is even less work then an intersection test
1806 if (BLI_in_rctf(bucket_bounds, cent[0], cent[1]))
1810 if((bucket_bounds->xmin <= cent[0] && bucket_bounds->xmax >= cent[0]) || (bucket_bounds->ymin <= cent[1] && bucket_bounds->ymax >= cent[1]) ) {
1814 /* out of bounds left */
1815 if (cent[0] < bucket_bounds->xmin) {
1816 /* lower left out of radius test */
1817 if (cent[1] < bucket_bounds->ymin) {
1818 return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmin, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
1821 else if (cent[1] > bucket_bounds->ymax) {
1822 return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmin, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
1825 else if (cent[0] > bucket_bounds->xmax) {
1826 /* lower right out of radius test */
1827 if (cent[1] < bucket_bounds->ymin) {
1828 return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmax, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
1830 /* top right test */
1831 else if (cent[1] > bucket_bounds->ymax) {
1832 return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmax, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
1841 /* Note for rect_to_uvspace_ortho() and rect_to_uvspace_persp()
1842 * in ortho view this function gives good results when bucket_bounds are outside the triangle
1843 * however in some cases, perspective view will mess up with faces that have minimal screenspace area (viewed from the side)
1845 * 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.
1846 * however switching back to this for ortho is always an option */
1848 static void rect_to_uvspace_ortho(
1849 rctf *bucket_bounds,
1850 float *v1coSS, float *v2coSS, float *v3coSS,
1851 float *uv1co, float *uv2co, float *uv3co,
1852 float bucket_bounds_uv[4][2],
1858 /* get the UV space bounding box */
1859 uv[0] = bucket_bounds->xmax;
1860 uv[1] = bucket_bounds->ymin;
1861 barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
1862 interp_v2_v2v2v2(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w);
1864 //uv[0] = bucket_bounds->xmax; // set above
1865 uv[1] = bucket_bounds->ymax;
1866 barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
1867 interp_v2_v2v2v2(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w);
1869 uv[0] = bucket_bounds->xmin;
1870 //uv[1] = bucket_bounds->ymax; // set above
1871 barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
1872 interp_v2_v2v2v2(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w);
1874 //uv[0] = bucket_bounds->xmin; // set above
1875 uv[1] = bucket_bounds->ymin;
1876 barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
1877 interp_v2_v2v2v2(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w);
1880 /* same as above but use barycentric_weights_v2_persp */
1881 static void rect_to_uvspace_persp(
1882 rctf *bucket_bounds,
1883 float *v1coSS, float *v2coSS, float *v3coSS,
1884 float *uv1co, float *uv2co, float *uv3co,
1885 float bucket_bounds_uv[4][2],
1892 /* get the UV space bounding box */
1893 uv[0] = bucket_bounds->xmax;
1894 uv[1] = bucket_bounds->ymin;
1895 barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
1896 interp_v2_v2v2v2(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w);
1898 //uv[0] = bucket_bounds->xmax; // set above
1899 uv[1] = bucket_bounds->ymax;
1900 barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
1901 interp_v2_v2v2v2(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w);
1903 uv[0] = bucket_bounds->xmin;
1904 //uv[1] = bucket_bounds->ymax; // set above
1905 barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
1906 interp_v2_v2v2v2(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w);
1908 //uv[0] = bucket_bounds->xmin; // set above
1909 uv[1] = bucket_bounds->ymin;
1910 barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
1911 interp_v2_v2v2v2(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w);
1914 /* This works as we need it to but we can save a few steps and not use it */
1917 static float angle_2d_clockwise(const float p1[2], const float p2[2], const float p3[2])
1921 v1[0] = p1[0]-p2[0]; v1[1] = p1[1]-p2[1];
1922 v2[0] = p3[0]-p2[0]; v2[1] = p3[1]-p2[1];
1924 return -atan2(v1[0]*v2[1] - v1[1]*v2[0], v1[0]*v2[0]+v1[1]*v2[1]);
1929 #define ISECT_2 (1<<1)
1930 #define ISECT_3 (1<<2)
1931 #define ISECT_4 (1<<3)
1932 #define ISECT_ALL3 ((1<<3)-1)
1933 #define ISECT_ALL4 ((1<<4)-1)
1935 /* limit must be a fraction over 1.0f */
1936 static int IsectPT2Df_limit(float pt[2], float v1[2], float v2[2], float v3[2], float limit)
1938 return ((area_tri_v2(pt,v1,v2) + area_tri_v2(pt,v2,v3) + area_tri_v2(pt,v3,v1)) / (area_tri_v2(v1,v2,v3))) < limit;
1941 /* Clip the face by a bucket and set the uv-space bucket_bounds_uv
1942 * so we have the clipped UV's to do pixel intersection tests with
1944 static int float_z_sort_flip(const void *p1, const void *p2)
1946 return (((float *)p1)[2] < ((float *)p2)[2] ? 1:-1);
1949 static int float_z_sort(const void *p1, const void *p2)
1951 return (((float *)p1)[2] < ((float *)p2)[2] ?-1:1);
1954 static void project_bucket_clip_face(
1956 rctf *bucket_bounds,
1957 float *v1coSS, float *v2coSS, float *v3coSS,
1958 float *uv1co, float *uv2co, float *uv3co,
1959 float bucket_bounds_uv[8][2],
1962 int inside_bucket_flag = 0;
1963 int inside_face_flag = 0;
1964 const int flip = ((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) != (line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
1966 float bucket_bounds_ss[4][2];
1968 /* get the UV space bounding box */
1969 inside_bucket_flag |= BLI_in_rctf(bucket_bounds, v1coSS[0], v1coSS[1]);
1970 inside_bucket_flag |= BLI_in_rctf(bucket_bounds, v2coSS[0], v2coSS[1]) << 1;
1971 inside_bucket_flag |= BLI_in_rctf(bucket_bounds, v3coSS[0], v3coSS[1]) << 2;
1973 if (inside_bucket_flag == ISECT_ALL3) {
1974 /* all screenspace points are inside the bucket bounding box, this means we dont need to clip and can simply return the UVs */
1975 if (flip) { /* facing the back? */
1976 copy_v2_v2(bucket_bounds_uv[0], uv3co);
1977 copy_v2_v2(bucket_bounds_uv[1], uv2co);
1978 copy_v2_v2(bucket_bounds_uv[2], uv1co);
1981 copy_v2_v2(bucket_bounds_uv[0], uv1co);
1982 copy_v2_v2(bucket_bounds_uv[1], uv2co);
1983 copy_v2_v2(bucket_bounds_uv[2], uv3co);
1990 /* get the UV space bounding box */
1991 /* use IsectPT2Df_limit here so we catch points are are touching the tri edge (or a small fraction over) */
1992 bucket_bounds_ss[0][0] = bucket_bounds->xmax;
1993 bucket_bounds_ss[0][1] = bucket_bounds->ymin;
1994 inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[0], v1coSS, v2coSS, v3coSS, 1+PROJ_GEOM_TOLERANCE) ? ISECT_1 : 0);
1996 bucket_bounds_ss[1][0] = bucket_bounds->xmax;
1997 bucket_bounds_ss[1][1] = bucket_bounds->ymax;
1998 inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[1], v1coSS, v2coSS, v3coSS, 1+PROJ_GEOM_TOLERANCE) ? ISECT_2 : 0);
2000 bucket_bounds_ss[2][0] = bucket_bounds->xmin;
2001 bucket_bounds_ss[2][1] = bucket_bounds->ymax;
2002 inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[2], v1coSS, v2coSS, v3coSS, 1+PROJ_GEOM_TOLERANCE) ? ISECT_3 : 0);
2004 bucket_bounds_ss[3][0] = bucket_bounds->xmin;
2005 bucket_bounds_ss[3][1] = bucket_bounds->ymin;
2006 inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[3], v1coSS, v2coSS, v3coSS, 1+PROJ_GEOM_TOLERANCE) ? ISECT_4 : 0);
2008 if (inside_face_flag == ISECT_ALL4) {
2009 /* bucket is totally inside the screenspace face, we can safely use weights */
2011 if (is_ortho) rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
2012 else rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
2018 /* The Complicated Case!
2020 * The 2 cases above are where the face is inside the bucket or the bucket is inside the face.
2022 * we need to make a convex polyline from the intersection between the screenspace face
2023 * and the bucket bounds.
2025 * There are a number of ways this could be done, currently it just collects all intersecting verts,
2026 * and line intersections, then sorts them clockwise, this is a lot easier then evaluating the geometry to
2027 * do a correct clipping on both shapes. */
2030 /* add a bunch of points, we know must make up the convex hull which is the clipped rect and triangle */
2034 /* Maximum possible 6 intersections when using a rectangle and triangle */
2035 float isectVCosSS[8][3]; /* The 3rd float is used to store angle for qsort(), NOT as a Z location */
2036 float v1_clipSS[2], v2_clipSS[2];
2040 float cent[2] = {0.0f, 0.0f};
2041 /*float up[2] = {0.0f, 1.0f};*/
2047 if (inside_face_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[0]); (*tot)++; }
2048 if (inside_face_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[1]); (*tot)++; }
2049 if (inside_face_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[2]); (*tot)++; }
2050 if (inside_face_flag & ISECT_4) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[3]); (*tot)++; }
2052 if (inside_bucket_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], v1coSS); (*tot)++; }
2053 if (inside_bucket_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], v2coSS); (*tot)++; }
2054 if (inside_bucket_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], v3coSS); (*tot)++; }
2056 if ((inside_bucket_flag & (ISECT_1|ISECT_2)) != (ISECT_1|ISECT_2)) {
2057 if (line_clip_rect2f(bucket_bounds, v1coSS, v2coSS, v1_clipSS, v2_clipSS)) {
2058 if ((inside_bucket_flag & ISECT_1)==0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
2059 if ((inside_bucket_flag & ISECT_2)==0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
2063 if ((inside_bucket_flag & (ISECT_2|ISECT_3)) != (ISECT_2|ISECT_3)) {
2064 if (line_clip_rect2f(bucket_bounds, v2coSS, v3coSS, v1_clipSS, v2_clipSS)) {
2065 if ((inside_bucket_flag & ISECT_2)==0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
2066 if ((inside_bucket_flag & ISECT_3)==0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
2070 if ((inside_bucket_flag & (ISECT_3|ISECT_1)) != (ISECT_3|ISECT_1)) {
2071 if (line_clip_rect2f(bucket_bounds, v3coSS, v1coSS, v1_clipSS, v2_clipSS)) {
2072 if ((inside_bucket_flag & ISECT_3)==0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
2073 if ((inside_bucket_flag & ISECT_1)==0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
2078 if ((*tot) < 3) { /* no intersections to speak of */
2083 /* now we have all points we need, collect their angles and sort them clockwise */
2085 for(i=0; i<(*tot); i++) {
2086 cent[0] += isectVCosSS[i][0];
2087 cent[1] += isectVCosSS[i][1];
2089 cent[0] = cent[0] / (float)(*tot);
2090 cent[1] = cent[1] / (float)(*tot);
2094 /* Collect angles for every point around the center point */
2097 #if 0 /* uses a few more cycles then the above loop */
2098 for(i=0; i<(*tot); i++) {
2099 isectVCosSS[i][2] = angle_2d_clockwise(up, cent, isectVCosSS[i]);
2103 v1_clipSS[0] = cent[0]; /* Abuse this var for the loop below */
2104 v1_clipSS[1] = cent[1] + 1.0f;
2106 for(i=0; i<(*tot); i++) {
2107 v2_clipSS[0] = isectVCosSS[i][0] - cent[0];
2108 v2_clipSS[1] = isectVCosSS[i][1] - cent[1];
2109 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]);
2112 if (flip) qsort(isectVCosSS, *tot, sizeof(float)*3, float_z_sort_flip);
2113 else qsort(isectVCosSS, *tot, sizeof(float)*3, float_z_sort);
2115 /* remove doubles */
2116 /* first/last check */
2117 if (fabsf(isectVCosSS[0][0]-isectVCosSS[(*tot)-1][0]) < PROJ_GEOM_TOLERANCE && fabsf(isectVCosSS[0][1]-isectVCosSS[(*tot)-1][1]) < PROJ_GEOM_TOLERANCE) {
2121 /* its possible there is only a few left after remove doubles */
2123 // printf("removed too many doubles A\n");
2129 while (doubles==TRUE) {
2131 for(i=1; i<(*tot); i++) {
2132 if (fabsf(isectVCosSS[i-1][0]-isectVCosSS[i][0]) < PROJ_GEOM_TOLERANCE &&
2133 fabsf(isectVCosSS[i-1][1]-isectVCosSS[i][1]) < PROJ_GEOM_TOLERANCE)
2136 for(j=i+1; j<(*tot); j++) {
2137 isectVCosSS[j-1][0] = isectVCosSS[j][0];
2138 isectVCosSS[j-1][1] = isectVCosSS[j][1];
2140 doubles = TRUE; /* keep looking for more doubles */
2146 /* its possible there is only a few left after remove doubles */
2148 // printf("removed too many doubles B\n");
2155 for(i=0; i<(*tot); i++) {
2156 barycentric_weights_v2(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w);
2157 interp_v2_v2v2v2(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
2161 for(i=0; i<(*tot); i++) {
2162 barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w);
2163 interp_v2_v2v2v2(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
2168 #ifdef PROJ_DEBUG_PRINT_CLIP
2169 /* include this at the bottom of the above function to debug the output */
2172 /* If there are ever any problems, */
2173 float test_uv[4][2];
2175 if (is_ortho) rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
2176 else rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
2177 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]);
2179 printf(" [(%f,%f), (%f,%f), (%f,%f)], ", uv1co[0], uv1co[1], uv2co[0], uv2co[1], uv3co[0], uv3co[1]);
2182 for (i=0; i < (*tot); i++) {
2183 printf("(%f, %f),", bucket_bounds_uv[i][0], bucket_bounds_uv[i][1]);
2191 # This script creates faces in a blender scene from printed data above.
2194 ...(output from above block)...
2197 from Blender import Scene, Mesh, Window, sys, Mathutils
2201 V = Mathutils.Vector
2204 sce = bpy.data.scenes.active
2206 for item in project_ls:
2211 me = bpy.data.meshes.new()
2212 ob = sce.objects.new(me)
2214 me.verts.extend([V(bb[0]).resize3D(), V(bb[1]).resize3D(), V(bb[2]).resize3D(), V(bb[3]).resize3D()])
2215 me.faces.extend([(0,1,2,3),])
2216 me.verts.extend([V(uv[0]).resize3D(), V(uv[1]).resize3D(), V(uv[2]).resize3D()])
2217 me.faces.extend([(4,5,6),])
2219 vs = [V(p).resize3D() for p in poly]
2225 while i < len(me.verts):
2227 if ii==len(me.verts):
2229 me.edges.extend([i, ii])
2232 if __name__ == '__main__':
2245 /* checks if pt is inside a convex 2D polyline, the polyline must be ordered rotating clockwise
2246 * otherwise it would have to test for mixed (line_point_side_v2 > 0.0f) cases */
2247 static int IsectPoly2Df(const float pt[2], float uv[][2], const int tot)
2250 if (line_point_side_v2(uv[tot-1], uv[0], pt) < 0.0f)
2253 for (i=1; i<tot; i++) {
2254 if (line_point_side_v2(uv[i-1], uv[i], pt) < 0.0f)
2261 static int IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot)
2264 int side = (line_point_side_v2(uv[tot-1], uv[0], pt) > 0.0f);
2266 for (i=1; i<tot; i++) {
2267 if ((line_point_side_v2(uv[i-1], uv[i], pt) > 0.0f) != side)
2275 /* One of the most important function for projectiopn painting, since it selects the pixels to be added into each bucket.
2276 * initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */
2277 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, const short clamp_u, const short clamp_v)
2279 /* Projection vars, to get the 3D locations into screen space */
2280 MemArena *arena = ps->arena_mt[thread_index];
2281 LinkNode **bucketPixelNodes = ps->bucketRect + bucket_index;
2282 LinkNode *bucketFaceNodes = ps->bucketFaces[bucket_index];
2284 const MFace *mf = ps->dm_mface + face_index;
2285 const MTFace *tf = ps->dm_mtface + face_index;
2287 /* UV/pixel seeking data */
2288 int x; /* Image X-Pixel */
2289 int y;/* Image Y-Pixel */
2291 float uv[2]; /* Image floating point UV - same as x, y but from 0.0-1.0 */
2294 float *v1coSS, *v2coSS, *v3coSS; /* vert co screen-space, these will be assigned to mf->v1,2,3 or mf->v1,3,4 */
2296 float *vCo[4]; /* vertex screenspace coords */
2300 float *uv1co, *uv2co, *uv3co; /* for convenience only, these will be assigned to tf->uv[0],1,2 or tf->uv[0],2,3 */
2301 float pixelScreenCo[4];
2303 rcti bounds_px; /* ispace bounds */
2304 /* vars for getting uvspace bounds */
2306 float tf_uv_pxoffset[4][2]; /* bucket bounds in UV space so we can init pixels only for this face, */
2307 float xhalfpx, yhalfpx;
2308 const float ibuf_xf = (float)ibuf->x, ibuf_yf = (float)ibuf->y;
2310 int has_x_isect = 0, has_isect = 0; /* for early loop exit */
2314 float uv_clip[8][2];
2316 const short is_ortho = ps->is_ortho;
2317 const short do_backfacecull = ps->do_backfacecull;
2318 const short do_clip= ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
2320 vCo[0] = ps->dm_mvert[mf->v1].co;
2321 vCo[1] = ps->dm_mvert[mf->v2].co;
2322 vCo[2] = ps->dm_mvert[mf->v3].co;
2325 /* Use tf_uv_pxoffset instead of tf->uv so we can offset the UV half a pixel
2326 * this is done so we can avoid offseting all the pixels by 0.5 which causes
2327 * problems when wrapping negative coords */
2328 xhalfpx = (0.5f+ (PROJ_GEOM_TOLERANCE/3.0f) ) / ibuf_xf;
2329 yhalfpx = (0.5f+ (PROJ_GEOM_TOLERANCE/4.0f) ) / ibuf_yf;
2331 /* Note about (PROJ_GEOM_TOLERANCE/x) above...
2332 Needed to add this offset since UV coords are often quads aligned to pixels.
2333 In this case pixels can be exactly between 2 triangles causing nasty
2336 This workaround can be removed and painting will still work on most cases
2337 but since the first thing most people try is painting onto a quad- better make it work.
2342 tf_uv_pxoffset[0][0] = tf->uv[0][0] - xhalfpx;
2343 tf_uv_pxoffset[0][1] = tf->uv[0][1] - yhalfpx;
2345 tf_uv_pxoffset[1][0] = tf->uv[1][0] - xhalfpx;
2346 tf_uv_pxoffset[1][1] = tf->uv[1][1] - yhalfpx;
2348 tf_uv_pxoffset[2][0] = tf->uv[2][0] - xhalfpx;
2349 tf_uv_pxoffset[2][1] = tf->uv[2][1] - yhalfpx;
2352 vCo[3] = ps->dm_mvert[ mf->v4 ].co;
2354 tf_uv_pxoffset[3][0] = tf->uv[3][0] - xhalfpx;
2355 tf_uv_pxoffset[3][1] = tf->uv[3][1] - yhalfpx;
2370 uv1co = tf_uv_pxoffset[i1]; // was tf->uv[i1];
2371 uv2co = tf_uv_pxoffset[i2]; // was tf->uv[i2];
2372 uv3co = tf_uv_pxoffset[i3]; // was tf->uv[i3];
2374 v1coSS = ps->screenCoords[ (*(&mf->v1 + i1)) ];
2375 v2coSS = ps->screenCoords[ (*(&mf->v1 + i2)) ];
2376 v3coSS = ps->screenCoords[ (*(&mf->v1 + i3)) ];
2378 /* This funtion gives is a concave polyline in UV space from the clipped quad and tri*/
2379 project_bucket_clip_face(
2380 is_ortho, bucket_bounds,
2381 v1coSS, v2coSS, v3coSS,
2382 uv1co, uv2co, uv3co,
2383 uv_clip, &uv_clip_tot
2386 /* sometimes this happens, better just allow for 8 intersectiosn even though there should be max 6 */
2388 if (uv_clip_tot>6) {
2389 printf("this should never happen! %d\n", uv_clip_tot);
2393 if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) {
2396 CLAMP(bounds_px.xmin, 0, ibuf->x);
2397 CLAMP(bounds_px.xmax, 0, ibuf->x);
2401 CLAMP(bounds_px.ymin, 0, ibuf->y);
2402 CLAMP(bounds_px.ymax, 0, ibuf->y);
2408 for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
2409 //uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
2410 uv[1] = (float)y / ibuf_yf; /* use pixel offset UV coords instead */
2413 for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
2414 //uv[0] = (((float)x) + 0.5f) / ibuf->x;
2415 uv[0] = (float)x / ibuf_xf; /* use pixel offset UV coords instead */
2417 /* Note about IsectPoly2Df_twoside, checking the face or uv flipping doesnt work,
2418 * could check the poly direction but better to do this */
2419 if( (do_backfacecull && IsectPoly2Df(uv, uv_clip, uv_clip_tot)) ||
2420 (do_backfacecull==0 && IsectPoly2Df_twoside(uv, uv_clip, uv_clip_tot))) {
2422 has_x_isect = has_isect = 1;
2424 if (is_ortho) screen_px_from_ortho(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
2425 else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
2427 /* a pitty we need to get the worldspace pixel location here */
2429 interp_v3_v3v3v3(wco, ps->dm_mvert[ (*(&mf->v1 + i1)) ].co, ps->dm_mvert[ (*(&mf->v1 + i2)) ].co, ps->dm_mvert[ (*(&mf->v1 + i3)) ].co, w);
2430 if(ED_view3d_test_clipping(ps->rv3d, wco, 1)) {
2431 continue; /* Watch out that no code below this needs to run */
2435 /* Is this UV visible from the view? - raytrace */
2436 /* project_paint_PickFace is less complex, use for testing */
2437 //if (project_paint_PickFace(ps, pixelScreenCo, w, &side) == face_index) {
2438 if (ps->do_occlude==0 || !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo)) {
2440 mask = project_paint_uvpixel_mask(ps, face_index, side, w);
2443 BLI_linklist_prepend_arena(
2445 project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, side, w),
2453 else if (has_x_isect) {
2454 /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
2461 #if 0 /* TODO - investigate why this dosnt work sometimes! it should! */
2462 /* no intersection for this entire row, after some intersection above means we can quit now */
2463 if (has_x_isect==0 && has_isect) {
2473 #ifndef PROJ_DEBUG_NOSEAMBLEED
2474 if (ps->seam_bleed_px > 0.0f) {
2477 if (ps->thread_tot > 1)
2478 BLI_lock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
2480 face_seam_flag = ps->faceSeamFlags[face_index];
2482 /* are any of our edges un-initialized? */
2483 if ((face_seam_flag & (PROJ_FACE_SEAM1|PROJ_FACE_NOSEAM1))==0 ||
2484 (face_seam_flag & (PROJ_FACE_SEAM2|PROJ_FACE_NOSEAM2))==0 ||
2485 (face_seam_flag & (PROJ_FACE_SEAM3|PROJ_FACE_NOSEAM3))==0 ||
2486 (face_seam_flag & (PROJ_FACE_SEAM4|PROJ_FACE_NOSEAM4))==0
2488 project_face_seams_init(ps, face_index, mf->v4);
2489 face_seam_flag = ps->faceSeamFlags[face_index];
2490 //printf("seams - %d %d %d %d\n", flag&PROJ_FACE_SEAM1, flag&PROJ_FACE_SEAM2, flag&PROJ_FACE_SEAM3, flag&PROJ_FACE_SEAM4);
2493 if ((face_seam_flag & (PROJ_FACE_SEAM1|PROJ_FACE_SEAM2|PROJ_FACE_SEAM3|PROJ_FACE_SEAM4))==0) {
2495 if (ps->thread_tot > 1)
2496 BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
2500 /* we have a seam - deal with it! */
2502 /* Now create new UV's for the seam face */
2503 float (*outset_uv)[2] = ps->faceSeamUVs[face_index];
2504 float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */
2507 float *vCoSS[4]; /* vertex screenspace coords */
2509 float bucket_clip_edges[2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */
2510 float edge_verts_inset_clip[2][3];
2511 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 */
2513 float seam_subsection[4][2];
2514 float fac1, fac2, ftot;
2517 if (outset_uv[0][0]==FLT_MAX) /* first time initialize */
2518 uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4);
2520 /* ps->faceSeamUVs cant be modified when threading, now this is done we can unlock */
2521 if (ps->thread_tot > 1)
2522 BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
2524 vCoSS[0] = ps->screenCoords[mf->v1];
2525 vCoSS[1] = ps->screenCoords[mf->v2];
2526 vCoSS[2] = ps->screenCoords[mf->v3];
2528 vCoSS[3] = ps->screenCoords[ mf->v4 ];
2530 /* PROJ_FACE_SCALE_SEAM must be slightly less then 1.0f */
2532 if (mf->v4) scale_quad(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
2533 else scale_tri(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
2536 if (mf->v4) scale_quad(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
2537 else scale_tri(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
2540 side = 0; /* for triangles this wont need to change */
2542 for (fidx1 = 0; fidx1 < (mf->v4 ? 4 : 3); fidx1++) {
2543 if (mf->v4) fidx2 = (fidx1==3) ? 0 : fidx1+1; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) */
2544 else fidx2 = (fidx1==2) ? 0 : fidx1+1; /* next fidx in the face (0,1,2) -> (1,2,0) */
2546 if ( (face_seam_flag & (1<<fidx1)) && /* 1<<fidx1 -> PROJ_FACE_SEAM# */
2547 line_clip_rect2f(bucket_bounds, vCoSS[fidx1], vCoSS[fidx2], bucket_clip_edges[0], bucket_clip_edges[1])
2550 ftot = len_v2v2(vCoSS[fidx1], vCoSS[fidx2]); /* screenspace edge length */
2552 if (ftot > 0.0f) { /* avoid div by zero */
2554 if (fidx1==2 || fidx2==2) side= 1;
2558 fac1 = len_v2v2(vCoSS[fidx1], bucket_clip_edges[0]) / ftot;
2559 fac2 = len_v2v2(vCoSS[fidx1], bucket_clip_edges[1]) / ftot;
2561 interp_v2_v2v2(seam_subsection[0], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac1);
2562 interp_v2_v2v2(seam_subsection[1], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac2);
2564 interp_v2_v2v2(seam_subsection[2], outset_uv[fidx1], outset_uv[fidx2], fac2);
2565 interp_v2_v2v2(seam_subsection[3], outset_uv[fidx1], outset_uv[fidx2], fac1);
2567 /* if the bucket_clip_edges values Z values was kept we could avoid this
2568 * Inset needs to be added so occlusion tests wont hit adjacent faces */
2569 interp_v3_v3v3(edge_verts_inset_clip[0], insetCos[fidx1], insetCos[fidx2], fac1);
2570 interp_v3_v3v3(edge_verts_inset_clip[1], insetCos[fidx1], insetCos[fidx2], fac2);
2573 if (pixel_bounds_uv(seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3], &bounds_px, ibuf->x, ibuf->y, 1)) {
2574 /* bounds between the seam rect and the uvspace bucket pixels */
2577 for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
2578 // uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
2579 uv[1] = (float)y / ibuf_yf; /* use offset uvs instead */
2582 for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
2583 //uv[0] = (((float)x) + 0.5f) / (float)ibuf->x;
2584 uv[0] = (float)x / ibuf_xf; /* use offset uvs instead */
2586 /* test we're inside uvspace bucket and triangle bounds */
2587 if (isect_point_quad_v2(uv, seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3])) {
2589 /* We need to find the closest point along the face edge,
2590 * getting the screen_px_from_*** wont work because our actual location
2591 * is not relevent, since we are outside the face, Use VecLerpf to find
2592 * our location on the side of the face's UV */
2594 if (is_ortho) screen_px_from_ortho(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
2595 else screen_px_from_persp(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
2598 /* Since this is a seam we need to work out where on the line this pixel is */
2599 //fac = line_point_factor_v2(uv, uv_seam_quad[0], uv_seam_quad[1]);
2601 fac = line_point_factor_v2(uv, seam_subsection[0], seam_subsection[1]);
2602 if (fac < 0.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[0]); }
2603 else if (fac > 1.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[1]); }
2604 else { interp_v3_v3v3(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac); }
2607 pixelScreenCo[3] = 1.0f;
2608 mul_m4_v4((float(*)[4])ps->projectMat, pixelScreenCo); /* cast because of const */
2609 pixelScreenCo[0] = (float)(ps->winx/2.0f)+(ps->winx/2.0f)*pixelScreenCo[0]/pixelScreenCo[3];
2610 pixelScreenCo[1] = (float)(ps->winy/2.0f)+(ps->winy/2.0f)*pixelScreenCo[1]/pixelScreenCo[3];
2611 pixelScreenCo[2] = pixelScreenCo[2]/pixelScreenCo[3]; /* Use the depth for bucket point occlusion */
2614 if (ps->do_occlude==0 || !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo)) {
2616 /* Only bother calculating the weights if we intersect */
2617 if (ps->do_mask_normal || ps->dm_mtface_clone) {
2619 /* get the UV on the line since we want to copy the pixels from there for bleeding */
2621 float fac= closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]);
2622 if (fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]);
2623 else if (fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]);
2626 barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], uv_close, w);
2629 barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[1], tf_uv_pxoffset[2], uv_close, w);
2631 #else /* this is buggy with quads, dont use for now */
2633 /* Cheat, we know where we are along the edge so work out the weights from that */
2634 fac = fac1 + (fac * (fac2-fac1));
2636 w[0]=w[1]=w[2]= 0.0;
2638 w[fidx1?fidx1-1:0] = 1.0f-fac;
2639 w[fidx2?fidx2-1:0] = fac;
2642 w[fidx1] = 1.0f-fac;
2648 /* a pitty we need to get the worldspace pixel location here */
2650 if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
2651 else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
2653 if(ED_view3d_test_clipping(ps->rv3d, wco, 1)) {
2654 continue; /* Watch out that no code below this needs to run */
2658 mask = project_paint_uvpixel_mask(ps, face_index, side, w);
2661 BLI_linklist_prepend_arena(
2663 project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, side, w),
2670 else if (has_x_isect) {
2671 /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
2676 #if 0 /* TODO - investigate why this dosnt work sometimes! it should! */
2677 /* no intersection for this entire row, after some intersection above means we can quit now */
2678 if (has_x_isect==0 && has_isect) {
2689 #endif // PROJ_DEBUG_NOSEAMBLEED
2693 /* takes floating point screenspace min/max and returns int min/max to be used as indices for ps->bucketRect, ps->bucketFlags */
2694 static void project_paint_bucket_bounds(const ProjPaintState *ps, const float min[2], const float max[2], int bucketMin[2], int bucketMax[2])
2696 /* divide by bucketWidth & bucketHeight so the bounds are offset in bucket grid units */
2697 /* XXX: the offset of 0.5 is always truncated to zero and the offset of 1.5f is always truncated to 1, is this really correct?? - jwilkins */
2698 bucketMin[0] = (int)((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 */
2699 bucketMin[1] = (int)((int)(((float)(min[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 0.5f);
2701 bucketMax[0] = (int)((int)(((float)(max[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 1.5f);
2702 bucketMax[1] = (int)((int)(((float)(max[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 1.5f);
2704 /* incase the rect is outside the mesh 2d bounds */
2705 CLAMP(bucketMin[0], 0, ps->buckets_x);
2706 CLAMP(bucketMin[1], 0, ps->buckets_y);
2708 CLAMP(bucketMax[0], 0, ps->buckets_x);
2709 CLAMP(bucketMax[1], 0, ps->buckets_y);
2712 /* set bucket_bounds to a screen space-aligned floating point bound-box */
2713 static void project_bucket_bounds(const ProjPaintState *ps, const int bucket_x, const int bucket_y, rctf *bucket_bounds)
2715 bucket_bounds->xmin = ps->screenMin[0]+((bucket_x)*(ps->screen_width / ps->buckets_x)); /* left */
2716 bucket_bounds->xmax = ps->screenMin[0]+((bucket_x+1)*(ps->screen_width / ps->buckets_x)); /* right */
2718 bucket_bounds->ymin = ps->screenMin[1]+((bucket_y)*(ps->screen_height / ps->buckets_y)); /* bottom */
2719 bucket_bounds->ymax = ps->screenMin[1]+((bucket_y+1)*(ps->screen_height / ps->buckets_y)); /* top */
2722 /* Fill this bucket with pixels from the faces that intersect it.
2724 * have bucket_bounds as an argument so we don;t need to give bucket_x/y the rect function needs */
2725 static void project_bucket_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, rctf *bucket_bounds)
2728 int face_index, image_index=0;
2730 Image *tpage_last = NULL, *tpage;
2733 if (ps->image_tot==1) {
2734 /* Simple loop, no context switching */
2735 ibuf = ps->projImages[0].ibuf;
2736 ima = ps->projImages[0].ima;
2738 for (node = ps->bucketFaces[bucket_index]; node; node= node->next) {
2739 project_paint_face_init(ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
2744 /* More complicated loop, switch between images */
2745 for (node = ps->bucketFaces[bucket_index]; node; node= node->next) {
2746 face_index = GET_INT_FROM_POINTER(node->link);
2748 /* Image context switching */
2749 tpage = project_paint_face_image(ps, face_index);
2750 if (tpage_last != tpage) {
2753 for (image_index=0; image_index < ps->image_tot; image_index++) {
2754 if (ps->projImages[image_index].ima == tpage_last) {
2755 ibuf = ps->projImages[image_index].ibuf;
2756 ima = ps->projImages[image_index].ima;
2761 /* context switching done */
2763 project_paint_face_init(ps, thread_index, bucket_index, face_index, image_index, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
2767 ps->bucketFlags[bucket_index] |= PROJ_BUCKET_INIT;
2771 /* We want to know if a bucket and a face overlap in screen-space
2773 * Note, if this ever returns false positives its not that bad, since a face in the bounding area will have its pixels
2774 * calculated when it might not be needed later, (at the moment at least)
2775 * obviously it shouldn't have bugs though */
2777 static int project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int bucket_y, const MFace *mf)