diff --git a/release/scripts/modules/bl_i18n_utils/merge_po.py b/release/scripts/modules/bl_i18n_utils/merge_po.py index b09e4daefbc..51e587ca4c8 100755 --- a/release/scripts/modules/bl_i18n_utils/merge_po.py +++ b/release/scripts/modules/bl_i18n_utils/merge_po.py @@ -31,16 +31,17 @@ import sys try: + import settings import utils except: - from . import utils + from . import (settings, utils) def main(): import argparse parser = argparse.ArgumentParser(description="" \ "Merge one or more .po files into the first dest one.\n" \ - "If a msgkey (msgid, msgctxt) is present in more than " \ + "If a msgkey (msgctxt, msgid) is present in more than " \ "one merged po, the one in the first file wins, unless " \ "it’s marked as fuzzy and one later is not.\n" \ "The fuzzy flag is removed if necessary.\n" \ diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index deac66e6154..b05c1ad4eaa 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -47,11 +47,16 @@ #ifndef USE_RASKTER +/* this is rather and annoying hack, use define to isolate it. + * problem is caused by scanfill removing edges on us. */ +#define USE_SCANFILL_EDGE_WORKAROUND + #define SPLINE_RESOL_CAP_PER_PIXEL 2 #define SPLINE_RESOL_CAP_MIN 8 #define SPLINE_RESOL_CAP_MAX 64 -#define BUCKET_PIXELS_PER_CELL 8 +/* found this gives best performance for high detail masks, values between 2 and 8 work best */ +#define BUCKET_PIXELS_PER_CELL 4 #define SF_EDGE_IS_BOUNDARY 0xff #define SF_KEYINDEX_TEMP_ID ((unsigned int) -1) @@ -60,8 +65,9 @@ #define TRI_VERT ((unsigned int) -1) /* for debugging add... */ +#ifndef NDEBUG /* printf("%u %u %u %u\n", _t[0], _t[1], _t[2], _t[3]); \ */ -#define FACE_ASSERT(face, vert_max) \ +# define FACE_ASSERT(face, vert_max) \ { \ unsigned int *_t = face; \ BLI_assert(_t[0] < vert_max); \ @@ -69,6 +75,10 @@ BLI_assert(_t[2] < vert_max); \ BLI_assert(_t[3] < vert_max || _t[3] == TRI_VERT); \ } (void)0 +#else + /* do nothing */ +# define FACE_ASSERT(face, vert_max) +#endif static void rotate_point_v2(float r_p[2], const float p[2], const float cent[2], const float angle, const float asp[2]) { @@ -542,6 +552,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas unsigned int sf_vert_tot = 0; unsigned int tot_feather_quads = 0; +#ifdef USE_SCANFILL_EDGE_WORKAROUND + unsigned int tot_boundary_used = 0; + unsigned int tot_boundary_found = 0; +#endif + if (masklay->restrictflag & MASK_RESTRICT_RENDER) { /* skip the layer */ mr_handle->layers_tot--; @@ -574,6 +589,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas if (do_feather) { diff_feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution_ex( spline, &tot_diff_feather_points, resol, TRUE); + BLI_assert(diff_feather_points); } else { tot_diff_feather_points = 0; @@ -655,8 +671,15 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas for (j = 0; j < tot_diff_point; j++) { ScanFillEdge *sf_edge = BLI_scanfill_edge_add(&sf_ctx, sf_vert_prev, sf_vert); - sf_edge->tmp.c = SF_EDGE_IS_BOUNDARY; +#ifdef USE_SCANFILL_EDGE_WORKAROUND + if (diff_feather_points) { + sf_edge->tmp.c = SF_EDGE_IS_BOUNDARY; + tot_boundary_used++; + } +#else + (void)sf_edge; +#endif sf_vert_prev = sf_vert; sf_vert = sf_vert->next; } @@ -871,10 +894,20 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas *(face++) = sf_edge->v1->keyindex; face_index++; FACE_ASSERT(face - 4, sf_vert_tot); + +#ifdef USE_SCANFILL_EDGE_WORKAROUND + tot_boundary_found++; +#endif } } } +#ifdef USE_SCANFILL_EDGE_WORKAROUND + if (tot_boundary_found != tot_boundary_used) { + BLI_assert(tot_boundary_found < tot_boundary_used); + } +#endif + /* feather only splines */ while (open_spline_index > 0) { const unsigned int vertex_offset = open_spline_ranges[--open_spline_index].vertex_offset; @@ -993,15 +1026,22 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas MEM_freeN(open_spline_ranges); - // fprintf(stderr, "%d %d\n", face_index, sf_face_tot + tot_feather_quads); +// fprintf(stderr, "%u %u (%u %u), %u\n", face_index, sf_tri_tot + tot_feather_quads, sf_tri_tot, tot_feather_quads, tot_boundary_used - tot_boundary_found); +#ifdef USE_SCANFILL_EDGE_WORKAROUND + BLI_assert(face_index + (tot_boundary_used - tot_boundary_found) == sf_tri_tot + tot_feather_quads); +#else BLI_assert(face_index == sf_tri_tot + tot_feather_quads); - +#endif { MaskRasterLayer *layer = &mr_handle->layers[masklay_index]; if (BLI_rctf_isect(&default_bounds, &bounds, &bounds)) { - layer->face_tot = sf_tri_tot + tot_feather_quads; +#ifdef USE_SCANFILL_EDGE_WORKAROUND + layer->face_tot = (sf_tri_tot + tot_feather_quads) - (tot_boundary_used - tot_boundary_found); +#else + layer->face_tot = (sf_tri_tot + tot_feather_quads); +#endif layer->face_coords = face_coords; layer->face_array = face_array; layer->bounds = bounds; @@ -1229,14 +1269,21 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x case MASK_BLEND_REPLACE: value = (value * (1.0f - layer->alpha)) + (value_layer * layer->alpha); break; + case MASK_BLEND_DIFFERENCE: + value = fabsf(value - value_layer); + break; default: /* same as add */ BLI_assert(0); value += value_layer; break; } + + /* clamp after applying each layer so we don't get + * issues subtracting after accumulating over 1.0f */ + CLAMP(value, 0.0f, 1.0f); } - return CLAMPIS(value, 0.0f, 1.0f); + return value; } #endif /* USE_RASKTER */ diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp index b10e99697e4..753940cd4f2 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cpp +++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp @@ -36,10 +36,13 @@ #include "BLI_threads.h" #if COM_CURRENT_THREADING_MODEL == COM_TM_NOTHREAD -#warning COM_CURRENT_THREADING_MODEL COM_TM_NOTHREAD is activated. Use only for debugging. +# ifndef DEBUG /* test this so we dont get warnings in debug builds */ +# warning COM_CURRENT_THREADING_MODEL COM_TM_NOTHREAD is activated. Use only for debugging. +# endif #elif COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE + /* do nothing - default */ #else -#error COM_CURRENT_THREADING_MODEL No threading model selected +# error COM_CURRENT_THREADING_MODEL No threading model selected #endif diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 6cfa828024d..c819637fd04 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -93,7 +93,7 @@ typedef struct { float ob_scale[3]; /* need temp space due to linked values */ float ob_dims[3]; short link_scale; - float ve_median[7]; + float ve_median[9]; int curdef; float *defweightp; } TransformProperties; @@ -135,13 +135,13 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL; MDeformVert *dvert = NULL; TransformProperties *tfp; - float median[7], ve_median[7]; - int tot, totw, totweight, totedge, totradius; + float median[9], ve_median[9]; + int tot, totw, totweight, totedge, totradius, totskinradius; char defstr[320]; PointerRNA radius_ptr; - median[0] = median[1] = median[2] = median[3] = median[4] = median[5] = median[6] = 0.0; - tot = totw = totweight = totedge = totradius = 0; + median[0] = median[1] = median[2] = median[3] = median[4] = median[5] = median[6] = median[7] = median[8] = 0.0; + tot = totw = totweight = totedge = totradius = totskinradius = 0; defstr[0] = 0; /* make sure we got storage */ @@ -159,9 +159,17 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + MVertSkin *vs; + evedef = eve; tot++; add_v3_v3(median, eve->co); + + vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); + if (vs) { + add_v2_v2(median + 7, vs->radius); /* Third val not used currently. */ + totskinradius++; + } } } @@ -304,6 +312,10 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float median[4] /= (float)totweight; if (totradius) median[5] /= (float)totradius; + if (totskinradius) { + median[7] /= (float)totskinradius; + median[8] /= (float)totskinradius; + } if (v3d->flag & V3D_GLOBAL_STATS) mul_m4_v3(ob->obmat, median); @@ -373,6 +385,23 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); } + if (totskinradius == 1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius X:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier")); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius Y:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier")); + } + else if (totskinradius > 1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius X:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("Median X radius used by Skin modifier")); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius Y:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Median Y radius used by Skin modifier")); + } + if (totedge == 1) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Crease:"), 0, yi -= buth + but_margin, 200, buth, @@ -407,6 +436,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float median[4] = ve_median[4] - median[4]; median[5] = ve_median[5] - median[5]; median[6] = ve_median[6] - median[6]; + median[7] = ve_median[7] - median[7]; + median[8] = ve_median[8] - median[8]; if (ob->type == OB_MESH) { Mesh *me = ob->data; @@ -501,6 +532,55 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } } + + if (median[7] != 0.0f) { + BMVert *eve; + /* That one is not clamped to [0.0, 1.0]. */ + float sca = ve_median[7]; + if (ve_median[7] - median[7] == 0.0f) { + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); + if (vs) + vs->radius[0] = sca; + } + } + } + else { + sca /= (ve_median[7] - median[7]); + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); + if (vs) + vs->radius[0] *= sca; + } + } + } + } + if (median[8] != 0.0f) { + BMVert *eve; + /* That one is not clamped to [0.0, 1.0]. */ + float sca = ve_median[8]; + if (ve_median[8] - median[8] == 0.0f) { + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); + if (vs) + vs->radius[1] = sca; + } + } + } + else { + sca /= (ve_median[8] - median[8]); + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); + if (vs) + vs->radius[1] *= sca; + } + } + } + } EDBM_mesh_normals_update(em); } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 8eb2371a598..0be871add75 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4920,7 +4920,7 @@ static int createSlideVerts(TransInfo *t) if (BM_elem_flag_test(e2, BM_ELEM_SELECT)) continue; - /* This test is only relevant if object is not wire-dranw! See [#32068]. */ + /* This test is only relevant if object is not wire-drawn! See [#32068]. */ if (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE && !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit)) continue; diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index 09b1772b0fa..869ce010b07 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -172,12 +172,13 @@ enum { /* masklay->blend */ enum { - MASK_BLEND_ADD = 0, - MASK_BLEND_SUBTRACT = 1, - MASK_BLEND_LIGHTEN = 2, - MASK_BLEND_DARKEN = 3, - MASK_BLEND_MUL = 4, - MASK_BLEND_REPLACE = 5, + MASK_BLEND_ADD = 0, + MASK_BLEND_SUBTRACT = 1, + MASK_BLEND_LIGHTEN = 2, + MASK_BLEND_DARKEN = 3, + MASK_BLEND_MUL = 4, + MASK_BLEND_REPLACE = 5, + MASK_BLEND_DIFFERENCE = 6 }; /* masklay->blend_flag */ diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index f417458212d..2987057aeb6 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -585,6 +585,7 @@ static void rna_def_mask_layer(BlenderRNA *brna) {MASK_BLEND_DARKEN, "DARKEN", 0, "Darken", ""}, {MASK_BLEND_MUL, "MUL", 0, "Multiply", ""}, {MASK_BLEND_REPLACE, "REPLACE", 0, "Replace", ""}, + {MASK_BLEND_DIFFERENCE, "DIFFERENCE", 0, "Difference", ""}, {0, NULL, 0, NULL, NULL} }; @@ -641,7 +642,7 @@ static void rna_def_mask_layer(BlenderRNA *brna) /* render settings */ prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "alpha"); - RNA_def_property_range(prop, 0.0, 1.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Opacity", "Render Opacity"); RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);