diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-02-13 12:09:28 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-02-13 12:12:28 +0400 |
commit | ae8327dbf3afcdb6a6a0335aceeaa58600d7f1d3 (patch) | |
tree | 79ee11570a6ebb3d0ce27aa35e524c0991c17fad /source/blender/blenkernel/intern/mask_rasterize.c | |
parent | c85e66e7fe6d12c8a1b33dec703e9bb342b9953b (diff) |
Mask: add option to detect self intersections
Diffstat (limited to 'source/blender/blenkernel/intern/mask_rasterize.c')
-rw-r--r-- | source/blender/blenkernel/intern/mask_rasterize.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 694f892f2c8..2c60f52578d 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -918,6 +918,10 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas unsigned int face_index; int scanfill_flag = 0; + bool is_isect = false; + ListBase isect_remvertbase = {NULL, NULL}; + ListBase isect_remedgebase = {NULL, NULL}; + /* now we have all the splines */ face_coords = MEM_mallocN((sizeof(float) * 3) * sf_vert_tot, "maskrast_face_coords"); @@ -941,12 +945,50 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas cos += 3; } + + /* --- inefficient self-intersect case --- */ + /* if self intersections are found, its too trickty to attempt to map vertices + * so just realloc and add entirely new vertices - the result of the self-intersect check + */ + if ((masklay->flag & MASK_LAYERFLAG_FILL_OVERLAP) && + (is_isect = BLI_scanfill_calc_self_isect(&sf_ctx, + &isect_remvertbase, + &isect_remedgebase))) + { + unsigned int sf_vert_tot_isect = (unsigned int)BLI_countlist(&sf_ctx.fillvertbase); + unsigned int i = sf_vert_tot; + + face_coords = MEM_reallocN(face_coords, sizeof(float[3]) * (sf_vert_tot + sf_vert_tot_isect)); + + cos = (float *)&face_coords[sf_vert_tot][0]; + + for (sf_vert = sf_ctx.fillvertbase.first; sf_vert; sf_vert = sf_vert->next) { + copy_v3_v3(cos, sf_vert->co); + sf_vert->tmp.u = i++; + cos += 3; + } + + sf_vert_tot += sf_vert_tot_isect; + + /* we need to calc polys after self intersect */ + scanfill_flag |= BLI_SCANFILL_CALC_POLYS; + } + /* --- end inefficient code --- */ + + /* main scan-fill */ if ((masklay->flag & MASK_LAYERFLAG_FILL_DISCRETE) == 0) scanfill_flag |= BLI_SCANFILL_CALC_HOLES; sf_tri_tot = (unsigned int)BLI_scanfill_calc_ex(&sf_ctx, scanfill_flag, zvec); + if (is_isect) { + /* add removed data back, we only need edges for feather, + * but add verts back so they get freed along with others */ + BLI_movelisttolist(&sf_ctx.fillvertbase, &isect_remvertbase); + BLI_movelisttolist(&sf_ctx.filledgebase, &isect_remedgebase); + } + face_array = MEM_mallocN(sizeof(*face_array) * ((size_t)sf_tri_tot + (size_t)tot_feather_quads), "maskrast_face_index"); face_index = 0; |