diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_image_proj.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_image_proj.c | 112 |
1 files changed, 75 insertions, 37 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 1285616e6a2..0a972e76c9a 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -172,7 +172,8 @@ BLI_INLINE unsigned char f_to_char(const float val) #define PROJ_SRC_VIEW_FILL 4 #define PROJ_VIEW_DATA_ID "view_data" -#define PROJ_VIEW_DATA_SIZE (4 * 4 + 4 * 4 + 3) /* viewmat + winmat + clipsta + clipend + is_ortho */ +/* viewmat + winmat + clipsta + clipend + is_ortho */ +#define PROJ_VIEW_DATA_SIZE (4 * 4 + 4 * 4 + 3) #define PROJ_BUCKET_NULL 0 #define PROJ_BUCKET_INIT (1 << 0) @@ -270,7 +271,8 @@ typedef struct ProjPaintState { /** store options per vert, now only store if the vert is pointing away from the view. */ char *vertFlags; - /** 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. */ + /** 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. */ int buckets_x; int buckets_y; @@ -458,7 +460,8 @@ typedef struct ProjPixel { * new mask value is lower then mask_accum */ unsigned short *mask_accum; - /* horrible hack, store tile valid flag pointer here to re-validate tiles used for anchored and drag-dot strokes */ + /* horrible hack, store tile valid flag pointer here to re-validate tiles + * used for anchored and drag-dot strokes */ bool *valid; PixelPointer origColor; @@ -687,7 +690,8 @@ static void uvco_to_wrapped_pxco(const float uv[2], int ibuf_x, int ibuf_y, floa *y = *y * ibuf_y - 0.5f; } -/* Set the top-most face color that the screen space coord 'pt' touches (or return 0 if none touch) */ +/* Set the top-most face color that the screen space coord 'pt' touches + * (or return 0 if none touch) */ static bool project_paint_PickColor( const ProjPaintState *ps, const float pt[2], float *rgba_fp, unsigned char *rgba, const bool interp) @@ -848,7 +852,8 @@ static int project_paint_occlude_ptv_clip( /* Check if a screenspace location is occluded by any other faces * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison - * and doesn't need to be correct in relation to X and Y coords (this is the case in perspective view) */ + * and doesn't need to be correct in relation to X and Y coords + * (this is the case in perspective view) */ static bool project_bucket_point_occluded( const ProjPaintState *ps, LinkNode *bucketFace, const int orig_face, const float pixelScreenCo[4]) @@ -1438,8 +1443,10 @@ static float project_paint_uvpixel_mask( BKE_image_release_ibuf(other_tpage, ibuf_other, NULL); - if (!ps->do_layer_stencil_inv) /* matching the gimps layer mask black/white rules, white==full opacity */ + if (!ps->do_layer_stencil_inv) { + /* matching the gimps layer mask black/white rules, white==full opacity */ mask = (1.0f - mask); + } if (mask == 0.0f) { return 0.0f; @@ -1795,7 +1802,8 @@ static bool line_clip_rect2f( } - if (fabsf(l1[0] - l2[0]) < PROJ_PIXEL_TOLERANCE) { /* this is a single point (or close to)*/ + /* this is a single point (or close to)*/ + if (fabsf(l1[0] - l2[0]) < PROJ_PIXEL_TOLERANCE) { if (BLI_rctf_isect_pt_v(rect, l1)) { copy_v2_v2(l1_clip, l1); copy_v2_v2(l2_clip, l2); @@ -1823,7 +1831,8 @@ static bool line_clip_rect2f( return 0; } - if (fabsf(l1[1] - l2[1]) < PROJ_PIXEL_TOLERANCE) { /* this is a single point (or close to)*/ + /* this is a single point (or close to)*/ + if (fabsf(l1[1] - l2[1]) < PROJ_PIXEL_TOLERANCE) { if (BLI_rctf_isect_pt_v(rect, l1)) { copy_v2_v2(l1_clip, l1); copy_v2_v2(l2_clip, l2); @@ -2200,7 +2209,8 @@ static void project_bucket_clip_face( float bucket_bounds_ss[4][2]; /* detect pathological case where face the three vertices are almost collinear in screen space. - * mostly those will be culled but when flood filling or with smooth shading it's a possibility */ + * mostly those will be culled but when flood filling or with + * smooth shading it's a possibility */ if (min_fff(dist_squared_to_line_v2(v1coSS, v2coSS, v3coSS), dist_squared_to_line_v2(v2coSS, v3coSS, v1coSS), dist_squared_to_line_v2(v3coSS, v1coSS, v2coSS)) < PROJ_PIXEL_TOLERANCE) @@ -2234,7 +2244,8 @@ static void project_bucket_clip_face( *tot = 3; return; } - /* handle pathological case here, no need for further intersections below since tringle area is almost zero */ + /* handle pathological case here, + * no need for further intersections below since tringle area is almost zero */ if (collinear) { int flag; @@ -2282,7 +2293,8 @@ static void project_bucket_clip_face( } /* get the UV space bounding box */ - /* use IsectPT2Df_limit here so we catch points are are touching the tri edge (or a small fraction over) */ + /* use IsectPT2Df_limit here so we catch points are are touching the tri edge + * (or a small fraction over) */ bucket_bounds_ss[0][0] = bucket_bounds->xmax; bucket_bounds_ss[0][1] = bucket_bounds->ymin; inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[0], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_1 : 0); @@ -2763,7 +2775,8 @@ static void project_paint_face_init( #if 0 /* TODO - investigate why this dosnt work sometimes! it should! */ - /* no intersection for this entire row, after some intersection above means we can quit now */ + /* no intersection for this entire row, + * after some intersection above means we can quit now */ if (has_x_isect == 0 && has_isect) { break; } @@ -2898,15 +2911,17 @@ static void project_paint_face_init( float fac; /* We need to find the closest point along the face edge, - * getting the screen_px_from_*** wont work because our actual location - * is not relevant, since we are outside the face, Use VecLerpf to find - * our location on the side of the face's UV */ + * getting the screen_px_from_*** wont work because our + * actual location is not relevant, since we are outside + * the face, Use VecLerpf to find our location on the side + * of the face's UV */ #if 0 if (is_ortho) screen_px_from_ortho(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo); else screen_px_from_persp(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo); #endif - /* Since this is a seam we need to work out where on the line this pixel is */ + /* Since this is a seam we need to work out where on + * the line this pixel is */ //fac = line_point_factor_v2(uv, uv_seam_quad[0], uv_seam_quad[1]); fac = resolve_quad_u_v2(uv, UNPACK4(seam_subsection)); interp_v3_v3v3(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac); @@ -2928,25 +2943,29 @@ static void project_paint_face_init( if (ps->do_mask_normal || ps->poly_to_loop_uv_clone) { const float uv_fac = fac1 + (fac * (fac2 - fac1)); #if 0 - /* get the UV on the line since we want to copy the pixels from there for bleeding */ + /* get the UV on the line since we want to copy the + * pixels from there for bleeding */ float uv_close[2]; interp_v2_v2v2(uv_close, lt_uv_pxoffset[fidx1], lt_uv_pxoffset[fidx2], uv_fac); barycentric_weights_v2(lt_uv_pxoffset[0], lt_uv_pxoffset[1], lt_uv_pxoffset[2], uv_close, w); #else - /* Cheat, we know where we are along the edge so work out the weights from that */ + /* Cheat, we know where we are along the edge + * so work out the weights from that */ w[0] = w[1] = w[2] = 0.0; w[fidx1] = 1.0f - uv_fac; w[fidx2] = uv_fac; #endif } - /* a pity we need to get the worldspace pixel location here */ + /* a pity we need to get the worldspace + * pixel location here */ if (do_clip || do_3d_mapping) { interp_v3_v3v3v3(wco, vCo[0], vCo[1], vCo[2], w); if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, true)) { - /* Watch out that no code below this needs to run */ + /* Watch out that no code below + * this needs to run */ continue; } } @@ -2965,13 +2984,15 @@ static void project_paint_face_init( } } else if (has_x_isect) { - /* assuming the face is not a bow-tie - we know we cant intersect again on the X */ + /* assuming the face is not a bow-tie - we know + * we cant intersect again on the X */ break; } } #if 0 /* TODO - investigate why this dosnt work sometimes! it should! */ - /* no intersection for this entire row, after some intersection above means we can quit now */ + /* no intersection for this entire row, + * after some intersection above means we can quit now */ if (has_x_isect == 0 && has_isect) { break; } @@ -2993,10 +3014,16 @@ static void project_paint_face_init( * Takes floating point screenspace min/max and * returns int min/max to be used as indices for ps->bucketRect, ps->bucketFlags */ -static void project_paint_bucket_bounds(const ProjPaintState *ps, const float min[2], const float max[2], int bucketMin[2], int bucketMax[2]) +static void project_paint_bucket_bounds( + const ProjPaintState *ps, + const float min[2], const float max[2], + int bucketMin[2], int bucketMax[2]) { /* divide by bucketWidth & bucketHeight so the bounds are offset in bucket grid units */ - /* 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 */ + + /* 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 */ + /* these offsets of 0.5 and 1.5 seem odd but they are correct */ bucketMin[0] = (int)((int)(((float)(min[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 0.5f); bucketMin[1] = (int)((int)(((float)(min[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 0.5f); @@ -3089,13 +3116,14 @@ static void project_bucket_init( /* We want to know if a bucket and a face overlap in screen-space * - * Note, if this ever returns false positives its not that bad, since a face in the bounding area will have its pixels - * calculated when it might not be needed later, (at the moment at least) + * Note, if this ever returns false positives its not that bad, since a face in the bounding area + * will have its pixels calculated when it might not be needed later, (at the moment at least) * obviously it shouldn't have bugs though */ static bool project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int bucket_y, const MLoopTri *lt) { - /* TODO - replace this with a tricker method that uses sideofline for all screenCoords's edges against the closest bucket corner */ + /* TODO - replace this with a tricker method that uses sideofline for all + * screenCoords's edges against the closest bucket corner */ const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) }; rctf bucket_bounds; float p1[2], p2[2], p3[2], p4[2]; @@ -3184,7 +3212,8 @@ static void project_paint_delayed_face_init(ProjPaintState *ps, const MLoopTri * } } - /* no intersection for this entire row, after some intersection above means we can quit now */ + /* no intersection for this entire row, + * after some intersection above means we can quit now */ if (has_x_isect == 0 && has_isect) { break; } @@ -3483,7 +3512,8 @@ static void proj_paint_state_vert_flags_init(ProjPaintState *ps) } if (ps->is_ortho) { - if (dot_v3v3(ps->viewDir, no) <= ps->normal_angle__cos) { /* 1 vert of this face is towards us */ + if (dot_v3v3(ps->viewDir, no) <= ps->normal_angle__cos) { + /* 1 vert of this face is towards us */ ps->vertFlags[a] |= PROJ_VERT_CULL; } } @@ -3493,7 +3523,8 @@ static void proj_paint_state_vert_flags_init(ProjPaintState *ps) if (UNLIKELY(ps->is_flip_object)) { negate_v3(viewDirPersp); } - if (dot_v3v3(viewDirPersp, no) <= ps->normal_angle__cos) { /* 1 vert of this face is towards us */ + if (dot_v3v3(viewDirPersp, no) <= ps->normal_angle__cos) { + /* 1 vert of this face is towards us */ ps->vertFlags[a] |= PROJ_VERT_CULL; } } @@ -3828,7 +3859,8 @@ static void project_paint_prepare_all_faces( /* don't allow using the same inage for painting and stencilling */ if (slot->ima == ps->stencil_ima) { /* While this shouldn't be used, face-winding reads all polys. - * It's less trouble to set all faces to valid UV's, avoiding NULL checks all over. */ + * It's less trouble to set all faces to valid UV's, + * avoiding NULL checks all over. */ ps->poly_to_loop_uv[lt->poly] = mloopuv_base; continue; } @@ -3903,7 +3935,8 @@ static void project_paint_prepare_all_faces( image_index = BLI_linklist_index(image_LinkList.list, tpage); - if (image_index == -1 && BKE_image_has_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */ + if (image_index == -1 && BKE_image_has_ibuf(tpage, NULL)) { + /* MemArena dosnt have an append func */ BLI_linklist_append(&image_LinkList, tpage); image_index = ps->image_tot; ps->image_tot++; @@ -4637,7 +4670,8 @@ static void *do_projectpaint_thread(void *ph_v) softenArena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "paint soften arena"); } - /* printf("brush bounds %d %d %d %d\n", bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */ + /* printf("brush bounds %d %d %d %d\n", + * bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */ while (project_bucket_iter_next(ps, &bucket_index, &bucket_bounds, pos)) { @@ -4836,7 +4870,8 @@ static void *do_projectpaint_thread(void *ph_v) float samplecos[3]; float texrgba[4]; - /* taking 3d copy to account for 3D mapping too. It gets concatenated during sampling */ + /* taking 3d copy to account for 3D mapping too. + * It gets concatenated during sampling */ if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) { copy_v3_v3(samplecos, projPixel->worldCoSS); } @@ -4845,7 +4880,8 @@ static void *do_projectpaint_thread(void *ph_v) samplecos[2] = 0.0f; } - /* note, for clone and smear, we only use the alpha, could be a special function */ + /* note, for clone and smear, + * we only use the alpha, could be a special function */ BKE_brush_sample_tex_3d(ps->scene, brush, samplecos, texrgba, thread_index, pool); copy_v3_v3(texrgb, texrgba); @@ -5186,7 +5222,8 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int Brush *brush = ps->brush; ps->tool = brush->imagepaint_tool; ps->blend = brush->blend; - /* only check for inversion for the soften tool, elsewhere, a resident brush inversion flag can cause issues */ + /* only check for inversion for the soften tool, elsewhere, + * a resident brush inversion flag can cause issues */ if (brush->imagepaint_tool == PAINT_TOOL_SOFTEN) { ps->mode = (((ps->mode == BRUSH_STROKE_INVERT) ^ ((brush->flag & BRUSH_DIR_IN) != 0)) ? BRUSH_STROKE_INVERT : BRUSH_STROKE_NORMAL); @@ -5670,7 +5707,8 @@ void BKE_paint_data_warning(struct ReportList *reports, bool uvs, bool mat, bool ); } -/* Make sure that active object has a material, and assign UVs and image layers if they do not exist */ +/* Make sure that active object has a material, + * and assign UVs and image layers if they do not exist */ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *mat, bool *tex, bool *stencil) { Mesh *me; |