diff options
author | Hans Goudey <h.goudey@me.com> | 2020-10-23 06:03:28 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2020-10-23 06:03:28 +0300 |
commit | 895f4620a032272844651444d42bda8a9978a38c (patch) | |
tree | 2999110eb07c4f74c3292b4c6637c114d2180236 /source | |
parent | fafed6234b2d1d7a3ab897fb128f0d39776ece37 (diff) | |
parent | c6281d5dc7c40c6fabef0873b3865eadcb09c63e (diff) |
Merge branch 'master' into geometry-nodes
Diffstat (limited to 'source')
111 files changed, 1134 insertions, 2110 deletions
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index bf84f5c57b3..03877957f42 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -40,9 +40,6 @@ struct rcti; int BLF_init(void); void BLF_exit(void); -void BLF_default_dpi(int dpi); -void BLF_default_set(int fontid); -int BLF_default(void); /* get default font ID so we can pass it to other functions */ void BLF_cache_clear(void); @@ -98,13 +95,6 @@ void BLF_batch_draw_begin(void); void BLF_batch_draw_flush(void); void BLF_batch_draw_end(void); -/* Draw the string using the default font, size and dpi. */ -void BLF_draw_default(float x, float y, float z, const char *str, size_t len) ATTR_NONNULL(); -void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len) ATTR_NONNULL(); - -/* Set size and DPI, and return default font ID. */ -int BLF_set_default(void); - /* Draw the string using the current font. */ void BLF_draw_ex(int fontid, const char *str, size_t len, struct ResultBLF *r_info) ATTR_NONNULL(2); @@ -257,6 +247,16 @@ void BLF_thumb_preview(const char *filename, int h, int channels) ATTR_NONNULL(); +/* blf_default.c */ +void BLF_default_dpi(int dpi); +void BLF_default_set(int fontid); +int BLF_default(void); /* get default font ID so we can pass it to other functions */ +/* Draw the string using the default font, size and dpi. */ +void BLF_draw_default(float x, float y, float z, const char *str, size_t len) ATTR_NONNULL(); +void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len) ATTR_NONNULL(); +/* Set size and DPI, and return default font ID. */ +int BLF_set_default(void); + /* blf_font_default.c */ int BLF_load_default(const bool unique); int BLF_load_mono_default(const bool unique); diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt index 3fd0dd95ef8..59a9072de57 100644 --- a/source/blender/blenfont/CMakeLists.txt +++ b/source/blender/blenfont/CMakeLists.txt @@ -38,6 +38,7 @@ set(INC_SYS set(SRC intern/blf.c + intern/blf_default.c intern/blf_dir.c intern/blf_font.c intern/blf_font_default.c diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index c8940add738..48f283e67b9 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -37,10 +37,6 @@ #include "MEM_guardedalloc.h" -#include "DNA_listBase.h" -#include "DNA_userdef_types.h" -#include "DNA_vec_types.h" - #include "BLI_math.h" #include "BLI_threads.h" @@ -48,9 +44,6 @@ #include "IMB_colormanagement.h" -#include "UI_interface.h" - -#include "GPU_immediate.h" #include "GPU_matrix.h" #include "GPU_shader.h" @@ -64,9 +57,6 @@ */ #define BLF_MAX_FONT 16 -/* call BLF_default_set first! */ -#define ASSERT_DEFAULT_SET BLI_assert(global_font_default != -1) - #define BLF_RESULT_CHECK_INIT(r_info) \ if (r_info) { \ memset(r_info, 0, sizeof(*(r_info))); \ @@ -76,10 +66,6 @@ /* Font array. */ static FontBLF *global_font[BLF_MAX_FONT] = {NULL}; -/* Default size and dpi, for BLF_draw_default. */ -static int global_font_default = -1; -static int global_font_dpi = 72; - /* XXX, should these be made into global_font_'s too? */ int blf_mono_font = -1; int blf_mono_font_render = -1; @@ -98,16 +84,11 @@ int BLF_init(void) global_font[i] = NULL; } - global_font_dpi = 72; + BLF_default_dpi(72); return blf_font_init(); } -void BLF_default_dpi(int dpi) -{ - global_font_dpi = dpi; -} - void BLF_exit(void) { for (int i = 0; i < BLF_MAX_FONT; i++) { @@ -132,6 +113,11 @@ void BLF_cache_clear(void) } } +bool blf_font_id_is_valid(int fontid) +{ + return blf_get(fontid) != NULL; +} + static int blf_search(const char *name) { for (int i = 0; i < BLF_MAX_FONT; i++) { @@ -155,20 +141,6 @@ static int blf_search_available(void) return -1; } -void BLF_default_set(int fontid) -{ - FontBLF *font = blf_get(fontid); - if (font || fontid == -1) { - global_font_default = fontid; - } -} - -int BLF_default(void) -{ - ASSERT_DEFAULT_SET; - return global_font_default; -} - bool BLF_has_glyph(int fontid, unsigned int unicode) { FontBLF *font = blf_get(fontid); @@ -515,37 +487,6 @@ void BLF_batch_draw_end(void) g_batch.enabled = false; } -void BLF_draw_default(float x, float y, float z, const char *str, size_t len) -{ - ASSERT_DEFAULT_SET; - - const uiStyle *style = UI_style_get(); - BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); - BLF_position(global_font_default, x, y, z); - BLF_draw(global_font_default, str, len); -} - -/* same as above but call 'BLF_draw_ascii' */ -void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len) -{ - ASSERT_DEFAULT_SET; - - const uiStyle *style = UI_style_get(); - BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); - BLF_position(global_font_default, x, y, z); - BLF_draw_ascii(global_font_default, str, len); /* XXX, use real length */ -} - -int BLF_set_default(void) -{ - ASSERT_DEFAULT_SET; - - const uiStyle *style = UI_style_get(); - BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); - - return global_font_default; -} - static void blf_draw_gl__start(FontBLF *font) { /* diff --git a/source/blender/blenfont/intern/blf_default.c b/source/blender/blenfont/intern/blf_default.c new file mode 100644 index 00000000000..7bbc865128d --- /dev/null +++ b/source/blender/blenfont/intern/blf_default.c @@ -0,0 +1,90 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup blf + * + * Default API, that uses Blender's user preferences for the default size. + */ + +#include "DNA_userdef_types.h" + +#include "BLI_assert.h" + +#include "BLF_api.h" + +#include "UI_interface.h" + +#include "blf_internal.h" + +/* call BLF_default_set first! */ +#define ASSERT_DEFAULT_SET BLI_assert(global_font_default != -1) + +/* Default size and dpi, for BLF_draw_default. */ +static int global_font_default = -1; +static int global_font_dpi = 72; + +void BLF_default_dpi(int dpi) +{ + global_font_dpi = dpi; +} + +void BLF_default_set(int fontid) +{ + if ((fontid == -1) || blf_font_id_is_valid(fontid)) { + global_font_default = fontid; + } +} + +int BLF_default(void) +{ + ASSERT_DEFAULT_SET; + return global_font_default; +} + +int BLF_set_default(void) +{ + ASSERT_DEFAULT_SET; + + const uiStyle *style = UI_style_get(); + BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); + + return global_font_default; +} + +void BLF_draw_default(float x, float y, float z, const char *str, size_t len) +{ + ASSERT_DEFAULT_SET; + + const uiStyle *style = UI_style_get(); + BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); + BLF_position(global_font_default, x, y, z); + BLF_draw(global_font_default, str, len); +} + +/* same as above but call 'BLF_draw_ascii' */ +void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len) +{ + ASSERT_DEFAULT_SET; + + const uiStyle *style = UI_style_get(); + BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); + BLF_position(global_font_default, x, y, z); + BLF_draw_ascii(global_font_default, str, len); /* XXX, use real length */ +} diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h index b616f47a897..ada772c53d2 100644 --- a/source/blender/blenfont/intern/blf_internal.h +++ b/source/blender/blenfont/intern/blf_internal.h @@ -43,6 +43,8 @@ char *blf_dir_metrics_search(const char *filename); int blf_font_init(void); void blf_font_exit(void); +bool blf_font_id_is_valid(int fontid); + void blf_draw_buffer__start(struct FontBLF *font); void blf_draw_buffer__end(void); diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 4e8775aefb3..db44a771095 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -180,6 +180,10 @@ void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm, const bool do_id_user); +void BKE_pose_ensure(struct Main *bmain, + struct Object *ob, + struct bArmature *arm, + const bool do_id_user); void BKE_pose_where_is(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); void BKE_pose_where_is_bone(struct Depsgraph *depsgraph, struct Scene *scene, diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index aed4dad05ad..987b64c217e 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -31,7 +31,7 @@ extern "C" { */ /* Blender major and minor version. */ -#define BLENDER_VERSION 291 +#define BLENDER_VERSION 292 /* Blender patch version for bugfix releases. */ #define BLENDER_VERSION_PATCH 0 /** Blender release cycle stage: alpha/beta/rc/release. */ @@ -39,7 +39,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 8 +#define BLENDER_FILE_SUBVERSION 0 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index fbdfc5b76a7..763011c8d92 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -36,7 +36,6 @@ struct DerivedMesh; struct MDisps; struct Mesh; struct ModifierData; -struct Multires; struct MultiresModifierData; struct Object; struct Scene; @@ -114,22 +113,12 @@ int multiresModifier_rebuild_subdiv(struct Depsgraph *depsgraph, struct MultiresModifierData *mmd, int rebuild_limit, bool switch_view_to_lower_level); -void multiresModifier_subdivide_legacy(struct MultiresModifierData *mmd, - struct Scene *scene, - struct Object *ob, - int updateblock, - int simple); void multiresModifier_sync_levels_ex(struct Object *ob_dst, struct MultiresModifierData *mmd_src, struct MultiresModifierData *mmd_dst); void multires_stitch_grids(struct Object *); -/* Related to the old multires */ -void multires_free(struct Multires *mr); -void multires_load_old(struct Object *ob, struct Mesh *me); -void multires_load_old_250(struct Mesh *); - void multiresModifier_scale_disp(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c index 44fc608530b..2038079744d 100644 --- a/source/blender/blenkernel/intern/appdir.c +++ b/source/blender/blenkernel/intern/appdir.c @@ -109,6 +109,7 @@ static bool is_appdir_init = false; void BKE_appdir_init(void) { #ifndef NDEBUG + BLI_assert(is_appdir_init == false); is_appdir_init = true; #endif } @@ -254,8 +255,12 @@ static bool test_path(char *targetpath, } /** - * Puts the value of the specified environment variable into *path if it exists - * and points at a directory. Returns true if this was done. + * Puts the value of the specified environment variable into \a path if it exists. + * + * \param check_is_dir: When true, checks if it points at a directory. + * + * \returns true when the value of the environment variable is stored + * at the address \a path points to. */ static bool test_env_path(char *path, const char *envvar, const bool check_is_dir) { @@ -266,13 +271,14 @@ static bool test_env_path(char *path, const char *envvar, const bool check_is_di return false; } + BLI_strncpy(path, env_path, FILE_MAX); + if (check_is_dir == false) { CLOG_INFO(&LOG, 3, "using env '%s' without test: '%s'", envvar, env_path); return true; } if (BLI_is_dir(env_path)) { - BLI_strncpy(path, env_path, FILE_MAX); CLOG_INFO(&LOG, 3, "env '%s' found: %s", envvar, env_path); return true; } diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index e0b12228162..4aa328fcb22 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2540,6 +2540,13 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_ for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { /* Find the custom B-Bone handles. */ BKE_pchan_rebuild_bbone_handles(pose, pchan); + /* Re-validate that we are still using a valid pchan form custom transform. */ + /* Note that we could store pointers of freed pchan in a GSet to speed this up, however this is + * supposed to be a rarely used feature, so for now assuming that always building that GSet + * would be less optimal. */ + if (pchan->custom_tx != NULL && BLI_findindex(&pose->chanbase, pchan->custom_tx) == -1) { + pchan->custom_tx = NULL; + } } /* printf("rebuild pose %s, %d bones\n", ob->id.name, counter); */ @@ -2566,6 +2573,19 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_ } } +/** + * Ensures object's pose is rebuilt if needed. + * + * \param bmain: May be NULL, only used to tag depsgraph as being dirty... + */ +void BKE_pose_ensure(Main *bmain, Object *ob, bArmature *arm, const bool do_id_user) +{ + BLI_assert(!ELEM(NULL, arm, ob)); + if ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC)) { + BKE_pose_rebuild(bmain, ob, arm, do_id_user); + } +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -2704,11 +2724,9 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob) if (ELEM(NULL, arm, scene)) { return; } - if ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC)) { - /* WARNING! passing NULL bmain here means we won't tag depsgraph's as dirty - - * hopefully this is OK. */ - BKE_pose_rebuild(NULL, ob, arm, true); - } + /* WARNING! passing NULL bmain here means we won't tag depsgraph's as dirty - + * hopefully this is OK. */ + BKE_pose_ensure(NULL, ob, arm, true); ctime = BKE_scene_frame_get(scene); /* not accurate... */ diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index da4d9ea485c..17243b328e8 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -1707,11 +1707,10 @@ void BKE_brush_sculpt_reset(Brush *br) case SCULPT_TOOL_SCRAPE: case SCULPT_TOOL_FILL: br->alpha = 0.7f; - br->area_radius_factor = 1.0f; + br->area_radius_factor = 0.5f; br->spacing = 7; br->flag |= BRUSH_ACCUMULATE; br->flag |= BRUSH_INVERT_TO_SCRAPE_FILL; - br->flag2 |= BRUSH_AREA_RADIUS_PRESSURE; break; case SCULPT_TOOL_ROTATE: br->alpha = 1.0; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 1eb374d1a08..7e9ee1ad153 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -569,10 +569,9 @@ void BKE_curve_texspace_get(Curve *cu, float r_loc[3], float r_size[3]) bool BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3]) { - Nurb *nu; int tot = 0; - for (nu = nurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, nurb) { int tot_nu; if (nu->type == CU_BEZIER) { tot_nu = nu->pntsu; @@ -596,39 +595,33 @@ bool BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3]) int BKE_nurbList_verts_count(ListBase *nurb) { - Nurb *nu; int tot = 0; - nu = nurb->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nurb) { if (nu->bezt) { tot += 3 * nu->pntsu; } else if (nu->bp) { tot += nu->pntsu * nu->pntsv; } - - nu = nu->next; } + return tot; } int BKE_nurbList_verts_count_without_handles(ListBase *nurb) { - Nurb *nu; int tot = 0; - nu = nurb->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nurb) { if (nu->bezt) { tot += nu->pntsu; } else if (nu->bp) { tot += nu->pntsu * nu->pntsv; } - - nu = nu->next; } + return tot; } @@ -636,7 +629,6 @@ int BKE_nurbList_verts_count_without_handles(ListBase *nurb) void BKE_nurb_free(Nurb *nu) { - if (nu == NULL) { return; } @@ -664,17 +656,12 @@ void BKE_nurb_free(Nurb *nu) void BKE_nurbList_free(ListBase *lb) { - Nurb *nu, *next; - if (lb == NULL) { return; } - nu = lb->first; - while (nu) { - next = nu->next; + LISTBASE_FOREACH_MUTABLE (Nurb *, nu, lb) { BKE_nurb_free(nu); - nu = next; } BLI_listbase_clear(lb); } @@ -747,16 +734,11 @@ Nurb *BKE_nurb_copy(Nurb *src, int pntsu, int pntsv) void BKE_nurbList_duplicate(ListBase *lb1, const ListBase *lb2) { - Nurb *nu, *nun; - BKE_nurbList_free(lb1); - nu = lb2->first; - while (nu) { - nun = BKE_nurb_duplicate(nu); - BLI_addtail(lb1, nun); - - nu = nu->next; + LISTBASE_FOREACH (const Nurb *, nu, lb2) { + Nurb *nurb_new = BKE_nurb_duplicate(nu); + BLI_addtail(lb1, nurb_new); } } @@ -2625,9 +2607,7 @@ static void bevlist_firstlast_direction_calc_from_bpoint(Nurb *nu, BevList *bl) void BKE_curve_bevelList_free(ListBase *bev) { - BevList *bl, *blnext; - for (bl = bev->first; bl != NULL; bl = blnext) { - blnext = bl->next; + LISTBASE_FOREACH_MUTABLE (BevList *, bl, bev) { if (bl->seglen != NULL) { MEM_freeN(bl->seglen); } @@ -2654,10 +2634,9 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) /* this function needs an object, because of tflag and upflag */ Curve *cu = ob->data; - Nurb *nu; BezTriple *bezt, *prevbezt; BPoint *bp; - BevList *bl, *blnew, *blnext; + BevList *blnew; BevPoint *bevp2, *bevp1 = NULL, *bevp0; const float treshold = 0.00001f; float min, inp; @@ -2685,12 +2664,11 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) /* STEP 1: MAKE POLYS */ BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); - nu = nurbs->first; if (cu->editnurb && ob->type != OB_FONT) { is_editmode = 1; } - for (; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, nurbs) { if (nu->hide && is_editmode) { continue; } @@ -2706,7 +2684,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) /* check we are a single point? also check we are not a surface and that the orderu is sane, * enforced in the UI but can go wrong possibly */ if (!BKE_nurb_check_valid_u(nu)) { - bl = MEM_callocN(sizeof(BevList), "makeBevelList1"); + BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList1"); bl->bevpoints = MEM_calloc_arrayN(1, sizeof(BevPoint), "makeBevelPoints1"); BLI_addtail(bev, bl); bl->nr = 0; @@ -2726,7 +2704,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) if (nu->type == CU_POLY) { len = nu->pntsu; - bl = MEM_callocN(sizeof(BevList), "makeBevelList2"); + BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList2"); bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints2"); if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) { bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList2_seglen"); @@ -2777,7 +2755,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) /* in case last point is not cyclic */ len = segcount * resolu + 1; - bl = MEM_callocN(sizeof(BevList), "makeBevelBPoints"); + BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelBPoints"); bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelBPointsPoints"); if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) { bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelBPoints_seglen"); @@ -2930,7 +2908,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) if (nu->pntsv == 1) { len = (resolu * segcount); - bl = MEM_callocN(sizeof(BevList), "makeBevelList3"); + BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList3"); bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints3"); if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) { bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList3_seglen"); @@ -2989,8 +2967,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) } /* STEP 2: DOUBLE POINTS AND AUTOMATIC RESOLUTION, REDUCE DATABLOCKS */ - bl = bev->first; - while (bl) { + LISTBASE_FOREACH (BevList *, bl, bev) { if (bl->nr) { /* null bevel items come from single points */ bool is_cyclic = bl->poly != -1; nr = bl->nr; @@ -3025,11 +3002,9 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) bevp1++; } } - bl = bl->next; } - bl = bev->first; - while (bl) { - blnext = bl->next; + + LISTBASE_FOREACH_MUTABLE (BevList *, bl, bev) { if (bl->nr && bl->dupe_nr) { nr = bl->nr - bl->dupe_nr + 1; /* +1 because vectorbezier sets flag too */ blnew = MEM_mallocN(sizeof(BevList), "makeBevelList4"); @@ -3043,7 +3018,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) blnew->seglen = bl->seglen; blnew->nr = 0; BLI_remlink(bev, bl); - BLI_insertlinkbefore(bev, blnext, blnew); /* to make sure bevlijst is tuned with nurblist */ + BLI_insertlinkbefore(bev, bl->next, blnew); /* to make sure bevlist is tuned with nurblist */ bevp0 = bl->bevpoints; bevp1 = blnew->bevpoints; nr = bl->nr; @@ -3061,26 +3036,22 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) MEM_freeN(bl); blnew->dupe_nr = 0; } - bl = blnext; } /* STEP 3: POLYS COUNT AND AUTOHOLE */ - bl = bev->first; poly = 0; - while (bl) { + LISTBASE_FOREACH (BevList *, bl, bev) { if (bl->nr && bl->poly >= 0) { poly++; bl->poly = poly; bl->hole = 0; } - bl = bl->next; } /* find extreme left points, also test (turning) direction */ if (poly > 0) { sd = sortdata = MEM_malloc_arrayN(poly, sizeof(struct BevelSort), "makeBevelList5"); - bl = bev->first; - while (bl) { + LISTBASE_FOREACH (BevList *, bl, bev) { if (bl->poly > 0) { BevPoint *bevp; @@ -3125,14 +3096,12 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) sd++; } - - bl = bl->next; } qsort(sortdata, poly, sizeof(struct BevelSort), vergxcobev); sd = sortdata + 1; for (a = 1; a < poly; a++, sd++) { - bl = sd->bl; /* is bl a hole? */ + BevList *bl = sd->bl; /* is bl a hole? */ sd1 = sortdata + (a - 1); for (b = a - 1; b >= 0; b--, sd1--) { /* all polys to the left */ if (sd1->bl->charidx == bl->charidx) { /* for text, only check matching char */ @@ -3149,7 +3118,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) sd = sortdata; for (a = 0; a < poly; a++, sd++) { if (sd->bl->hole == sd->dir) { - bl = sd->bl; + BevList *bl = sd->bl; bevp1 = bl->bevpoints; bevp2 = bevp1 + (bl->nr - 1); nr = bl->nr / 2; @@ -3167,7 +3136,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) /* STEP 4: 2D-COSINES or 3D ORIENTATION */ if ((cu->flag & CU_3D) == 0) { /* 2D Curves */ - for (bl = bev->first; bl; bl = bl->next) { + LISTBASE_FOREACH (BevList *, bl, bev) { if (bl->nr < 2) { BevPoint *bevp = bl->bevpoints; unit_qt(bevp->quat); @@ -3182,7 +3151,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) } else { /* 3D Curves */ - for (bl = bev->first; bl; bl = bl->next) { + LISTBASE_FOREACH (BevList *, bl, bev) { if (bl->nr < 2) { BevPoint *bevp = bl->bevpoints; unit_qt(bevp->quat); @@ -4316,12 +4285,8 @@ void BKE_nurb_handles_autocalc(Nurb *nu, uint8_t flag) void BKE_nurbList_handles_autocalc(ListBase *editnurb, uint8_t flag) { - Nurb *nu; - - nu = editnurb->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { BKE_nurb_handles_autocalc(nu, flag); - nu = nu->next; } } @@ -4333,13 +4298,11 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code) /* code==4: sets icu flag to become IPO_AUTO_HORIZ, horizontal extremes on auto-handles */ /* code==5: Set align, like 3 but no toggle */ /* code==6: Clear align, like 3 but no toggle */ - Nurb *nu; BezTriple *bezt; int a; if (ELEM(code, HD_AUTO, HD_VECT)) { - nu = editnurb->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -4366,7 +4329,6 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code) /* like BKE_nurb_handles_calc but moves selected */ nurb_handles_calc__align_selected(nu); } - nu = nu->next; } } else { @@ -4381,7 +4343,7 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code) } else { /* Toggle */ - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -4397,7 +4359,7 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code) } h_new = (h_new == HD_FREE) ? HD_ALIGN : HD_FREE; } - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -4423,11 +4385,10 @@ void BKE_nurbList_handles_recalculate(ListBase *editnurb, const bool calc_length, const uint8_t flag) { - Nurb *nu; BezTriple *bezt; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bool changed = false; @@ -4477,12 +4438,11 @@ void BKE_nurbList_handles_recalculate(ListBase *editnurb, void BKE_nurbList_flag_set(ListBase *editnurb, uint8_t flag, bool set) { - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { a = nu->pntsu; bezt = nu->bezt; @@ -4518,7 +4478,7 @@ bool BKE_nurbList_flag_set_from_flag(ListBase *editnurb, uint8_t from_flag, uint { bool changed = false; - for (Nurb *nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { for (int i = 0; i < nu->pntsu; i++) { BezTriple *bezt = &nu->bezt[i]; @@ -5232,12 +5192,11 @@ bool BKE_curve_minmax(Curve *cu, bool use_radius, float min[3], float max[3]) bool BKE_curve_center_median(Curve *cu, float cent[3]) { ListBase *nurb_lb = BKE_curve_nurbs_get(cu); - Nurb *nu; int total = 0; zero_v3(cent); - for (nu = nurb_lb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, nurb_lb) { int i; if (nu->type == CU_BEZIER) { @@ -5285,12 +5244,11 @@ void BKE_curve_transform_ex(Curve *cu, const bool do_props, const float unit_scale) { - Nurb *nu; BPoint *bp; BezTriple *bezt; int i; - for (nu = cu->nurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { if (nu->type == CU_BEZIER) { i = nu->pntsu; for (bezt = nu->bezt; i--; bezt++) { @@ -5320,7 +5278,7 @@ void BKE_curve_transform_ex(Curve *cu, float *fp = kb->data; int n = kb->totelem; - for (nu = cu->nurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { if (nu->type == CU_BEZIER) { for (i = nu->pntsu; i && (n -= KEYELEM_ELEM_LEN_BEZTRIPLE) >= 0; i--) { mul_m4_v3(mat, &fp[0]); diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index bcb467e1230..ff03731b2aa 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -92,17 +92,13 @@ void BKE_displist_free(ListBase *lb) DispList *BKE_displist_find_or_create(ListBase *lb, int type) { - DispList *dl; - - dl = lb->first; - while (dl) { + LISTBASE_FOREACH (DispList *, dl, lb) { if (dl->type == type) { return dl; } - dl = dl->next; } - dl = MEM_callocN(sizeof(DispList), "find_disp"); + DispList *dl = MEM_callocN(sizeof(DispList), "find_disp"); dl->type = type; BLI_addtail(lb, dl); @@ -111,14 +107,10 @@ DispList *BKE_displist_find_or_create(ListBase *lb, int type) DispList *BKE_displist_find(ListBase *lb, int type) { - DispList *dl; - - dl = lb->first; - while (dl) { + LISTBASE_FOREACH (DispList *, dl, lb) { if (dl->type == type) { return dl; } - dl = dl->next; } return NULL; @@ -126,9 +118,7 @@ DispList *BKE_displist_find(ListBase *lb, int type) bool BKE_displist_has_faces(ListBase *lb) { - DispList *dl; - - for (dl = lb->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, lb) { if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) { return true; } @@ -139,13 +129,10 @@ bool BKE_displist_has_faces(ListBase *lb) void BKE_displist_copy(ListBase *lbn, ListBase *lb) { - DispList *dln, *dl; - BKE_displist_free(lbn); - dl = lb->first; - while (dl) { - dln = MEM_dupallocN(dl); + LISTBASE_FOREACH (const DispList *, dl, lb) { + DispList *dln = MEM_dupallocN(dl); BLI_addtail(lbn, dln); dln->verts = MEM_dupallocN(dl->verts); dln->nors = MEM_dupallocN(dl->nors); @@ -154,22 +141,18 @@ void BKE_displist_copy(ListBase *lbn, ListBase *lb) if (dl->bevel_split) { dln->bevel_split = MEM_dupallocN(dl->bevel_split); } - - dl = dl->next; } } void BKE_displist_normals_add(ListBase *lb) { - DispList *dl = NULL; float *vdata, *ndata, nor[3]; float *v1, *v2, *v3, *v4; float *n1, *n2, *n3, *n4; int a, b, p1, p2, p3, p4; - dl = lb->first; + LISTBASE_FOREACH (DispList *, dl, lb) { - while (dl) { if (dl->type == DL_INDEX3) { if (dl->nors == NULL) { dl->nors = MEM_callocN(sizeof(float[3]), "dlnors"); @@ -230,15 +213,12 @@ void BKE_displist_normals_add(ListBase *lb) } } } - dl = dl->next; } } void BKE_displist_count(ListBase *lb, int *totvert, int *totface, int *tottri) { - DispList *dl; - - for (dl = lb->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, lb) { int vert_tot = 0; int face_tot = 0; int tri_tot = 0; @@ -318,7 +298,6 @@ static void curve_to_displist(Curve *cu, ListBase *dispbase, const bool for_render) { - Nurb *nu; DispList *dl; BezTriple *bezt, *prevbezt; BPoint *bp; @@ -326,8 +305,7 @@ static void curve_to_displist(Curve *cu, int a, len, resolu; const bool editmode = (!for_render && (cu->editnurb || cu->editfont)); - nu = nubase->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nubase) { if (nu->hide == 0 || editmode == false) { if (for_render && cu->resolu_ren != 0) { resolu = cu->resolu_ren; @@ -473,7 +451,6 @@ static void curve_to_displist(Curve *cu, } } } - nu = nu->next; } } @@ -627,19 +604,17 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase) { const float z_up[3] = {0.0f, 0.0f, -1.0f}; ListBase front, back; - DispList *dl, *dlnew; float *fp, *fp1; int a, dpoly; BLI_listbase_clear(&front); BLI_listbase_clear(&back); - dl = dispbase->first; - while (dl) { + LISTBASE_FOREACH (DispList *, dl, dispbase) { if (dl->type == DL_SURF) { if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U) == 0) { if ((cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE)) { - dlnew = MEM_callocN(sizeof(DispList), "filldisp"); + DispList *dlnew = MEM_callocN(sizeof(DispList), "filldisp"); BLI_addtail(&front, dlnew); dlnew->verts = fp1 = MEM_mallocN(sizeof(float[3]) * dl->parts, "filldisp1"); dlnew->nr = dl->parts; @@ -660,7 +635,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase) } } if ((cu->flag & CU_FRONT) && (dl->flag & DL_FRONT_CURVE)) { - dlnew = MEM_callocN(sizeof(DispList), "filldisp"); + DispList *dlnew = MEM_callocN(sizeof(DispList), "filldisp"); BLI_addtail(&back, dlnew); dlnew->verts = fp1 = MEM_mallocN(sizeof(float[3]) * dl->parts, "filldisp1"); dlnew->nr = dl->parts; @@ -682,7 +657,6 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase) } } } - dl = dl->next; } BKE_displist_fill(&front, dispbase, z_up, true); @@ -939,18 +913,17 @@ static bool curve_calc_modifiers_pre( static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[3] { - DispList *dl; float(*allverts)[3], *fp; *r_vert_len = 0; - for (dl = dispbase->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, dispbase) { *r_vert_len += (dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr; } allverts = MEM_mallocN(sizeof(float[3]) * (*r_vert_len), "displist_vert_coords_alloc allverts"); fp = (float *)allverts; - for (dl = dispbase->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, dispbase) { int offs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr); memcpy(fp, dl->verts, sizeof(float) * offs); fp += offs; @@ -961,11 +934,10 @@ static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[ static void displist_vert_coords_apply(ListBase *dispbase, float (*allverts)[3]) { - DispList *dl; const float *fp; fp = (float *)allverts; - for (dl = dispbase->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, dispbase) { int offs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr); memcpy(dl->verts, fp, sizeof(float) * offs); fp += offs; @@ -1218,7 +1190,6 @@ void BKE_displist_make_surf(Depsgraph *depsgraph, const bool for_orco) { ListBase nubase = {NULL, NULL}; - Nurb *nu; Curve *cu = ob->data; DispList *dl; float *data; @@ -1236,7 +1207,7 @@ void BKE_displist_make_surf(Depsgraph *depsgraph, force_mesh_conversion = curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); } - for (nu = nubase.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &nubase) { if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) { int resolu = nu->resolu, resolv = nu->resolv; @@ -1851,12 +1822,11 @@ void BKE_displist_make_curveTypes_forRender(Depsgraph *depsgraph, void BKE_displist_minmax(ListBase *dispbase, float min[3], float max[3]) { - DispList *dl; const float *vert; int a, tot = 0; int doit = 0; - for (dl = dispbase->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, dispbase) { tot = (dl->type == DL_INDEX3) ? dl->nr : dl->nr * dl->parts; vert = dl->verts; for (a = 0; a < tot; a++, vert += 3) { diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index fafcbaec10f..dcf4c78dfd8 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -842,7 +842,8 @@ bool BKE_fcurve_calc_range( void BKE_fcurve_active_keyframe_set(FCurve *fcu, const BezTriple *active_bezt) { /* The active keyframe should always be selected. */ - BLI_assert(active_bezt == NULL || (active_bezt->f2 & SELECT)); + BLI_assert((active_bezt == NULL) || + ((active_bezt->f1 | active_bezt->f2 | active_bezt->f3) & SELECT)); fcu->active_keyframe_index = (active_bezt == NULL) ? FCURVE_ACTIVE_KEYFRAME_NONE : active_bezt - fcu->bezt; } @@ -861,7 +862,7 @@ int BKE_fcurve_active_keyframe_index(const FCurve *fcu) } const BezTriple *active_bezt = &fcu->bezt[active_keyframe_index]; - if ((active_bezt->f2 & SELECT) == 0) { + if (((active_bezt->f1 | active_bezt->f2 | active_bezt->f3) & SELECT) == 0) { /* The active keyframe should always be selected. If it's not selected, it can't be active. */ return FCURVE_ACTIVE_KEYFRAME_NONE; } diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 31cd812f8df..6c6ca996caa 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -2549,17 +2549,17 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer, /* Use evaluated frame (with modifiers for active stroke)/ */ act_gpf = gpl->actframe; if (act_gpf) { + act_gpf->runtime.onion_id = 0; + if (layer_cb) { + layer_cb(gpl, act_gpf, NULL, thunk); + } + /* If layer solo mode and Paint mode, only keyframes with data are displayed. */ if (GPENCIL_PAINT_MODE(gpd) && (gpl->flag & GP_LAYER_SOLO_MODE) && (act_gpf->framenum != cfra)) { continue; } - act_gpf->runtime.onion_id = 0; - if (layer_cb) { - layer_cb(gpl, act_gpf, NULL, thunk); - } - LISTBASE_FOREACH (bGPDstroke *, gps, &act_gpf->strokes) { if (gps->totpoints == 0) { continue; diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index 27422440cd5..ae6ee71da82 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -1884,6 +1884,9 @@ void BKE_library_make_local(Main *bmain, if (id->lib == NULL) { id->tag &= ~(LIB_TAG_EXTERN | LIB_TAG_INDIRECT | LIB_TAG_NEW); id->flag &= ~LIB_INDIRECT_WEAK_LINK; + if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) { + BKE_lib_override_library_free(&id->override_library, true); + } } /* The check on the fourth line (LIB_TAG_PRE_EXISTING) is done so it's possible to tag data * you don't want to be made local, used for appending data, diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index e008058ae39..3bac0cf6289 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -1422,6 +1422,15 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for FOREACH_MAIN_ID_BEGIN (bmain, id) { if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && (force_auto || (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH))) { + /* Usual issue with pose, it's quiet rare but sometimes they may not be up to date when this + * function is called. */ + if (GS(id->name) == ID_OB) { + Object *ob = (Object *)id; + if (ob->type == OB_ARMATURE) { + BLI_assert(ob->data != NULL); + BKE_pose_ensure(bmain, ob, ob->data, true); + } + } /* Only check overrides if we do have the real reference data available, and not some empty * 'placeholder' for missing data (broken links). */ if ((id->override_library->reference->tag & LIB_TAG_MISSING) == 0) { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 6ea83cf4330..97520654e7b 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -275,50 +275,6 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id) mesh->totselect = 0; } - /* Multires data */ - BLO_read_data_address(reader, &mesh->mr); - if (mesh->mr) { - BLO_read_list(reader, &mesh->mr->levels); - MultiresLevel *lvl = mesh->mr->levels.first; - - CustomData_blend_read(reader, &mesh->mr->vdata, lvl->totvert); - BKE_defvert_blend_read( - reader, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT)); - CustomData_blend_read(reader, &mesh->mr->fdata, lvl->totface); - - BLO_read_data_address(reader, &mesh->mr->edge_flags); - BLO_read_data_address(reader, &mesh->mr->edge_creases); - - BLO_read_data_address(reader, &mesh->mr->verts); - - /* If mesh has the same number of vertices as the - * highest multires level, load the current mesh verts - * into multires and discard the old data. Needed - * because some saved files either do not have a verts - * array, or the verts array contains out-of-date - * data. */ - if (mesh->totvert == ((MultiresLevel *)mesh->mr->levels.last)->totvert) { - if (mesh->mr->verts) { - MEM_freeN(mesh->mr->verts); - } - mesh->mr->verts = MEM_dupallocN(mesh->mvert); - } - - for (; lvl; lvl = lvl->next) { - BLO_read_data_address(reader, &lvl->verts); - BLO_read_data_address(reader, &lvl->faces); - BLO_read_data_address(reader, &lvl->edges); - BLO_read_data_address(reader, &lvl->colfaces); - } - } - - /* if multires is present but has no valid vertex data, - * there's no way to recover it; silently remove multires */ - if (mesh->mr && !mesh->mr->verts) { - multires_free(mesh->mr); - mesh->mr = NULL; - } - if ((BLO_read_requires_endian_switch(reader)) && mesh->tface) { TFace *tf = mesh->tface; for (int i = 0; i < mesh->totface; i++, tf++) { diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 6e1168d8a16..d7ea662a5d6 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -63,7 +63,6 @@ #include <string.h> /* MULTIRES MODIFIER */ -static const int multires_max_levels = 13; static const int multires_grid_tot[] = { 0, 4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409}; static const int multires_side_tot[] = { @@ -76,7 +75,6 @@ typedef enum { ADD_DISPLACEMENTS, } DispOp; -static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert); static void multiresModifier_disp_run( DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl); @@ -241,40 +239,6 @@ static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level) md->hidden = subd; } -static MDisps *multires_mdisps_init_hidden(Mesh *me, int level) -{ - MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop); - int gridsize = BKE_ccg_gridsize(level); - int gridarea = square_i(gridsize); - int i, j; - - for (i = 0; i < me->totpoly; i++) { - bool hide = false; - - for (j = 0; j < me->mpoly[i].totloop; j++) { - if (me->mvert[me->mloop[me->mpoly[i].loopstart + j].v].flag & ME_HIDE) { - hide = true; - break; - } - } - - if (!hide) { - continue; - } - - for (j = 0; j < me->mpoly[i].totloop; j++) { - MDisps *md = &mdisps[me->mpoly[i].loopstart + j]; - - BLI_assert(!md->hidden); - - md->hidden = BLI_BITMAP_NEW(gridarea, "MDisps.hidden initialize"); - BLI_bitmap_set_all(md->hidden, true, gridarea); - } - } - - return mdisps; -} - Mesh *BKE_multires_create_mesh(struct Depsgraph *depsgraph, Object *object, MultiresModifierData *mmd) @@ -429,12 +393,6 @@ void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl) mmd->renderlvl = CLAMPIS(MAX2(mmd->renderlvl, lvl), 0, mmd->totlvl); } -static void multires_dm_mark_as_modified(DerivedMesh *dm, MultiresModifiedFlags flags) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; - ccgdm->multires.modified_flags |= flags; -} - static void multires_ccg_mark_as_modified(SubdivCCG *subdiv_ccg, MultiresModifiedFlags flags) { if (flags & MULTIRES_COORDS_MODIFIED) { @@ -850,110 +808,6 @@ static DerivedMesh *subsurf_dm_create_local(Scene *scene, return subsurf_make_derived_from_derived(dm, &smd, scene, NULL, flags); } -static void multires_subdivide_legacy( - MultiresModifierData *mmd, Scene *scene, Object *ob, int totlvl, int updateblock, int simple) -{ - Mesh *me = ob->data; - MDisps *mdisps; - const int lvl = mmd->totlvl; - - if ((totlvl > multires_max_levels) || (me->totpoly == 0)) { - return; - } - - BLI_assert(totlvl > lvl); - - multires_force_sculpt_rebuild(ob); - - mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); - if (!mdisps) { - mdisps = multires_mdisps_init_hidden(me, totlvl); - } - - if (mdisps->disps && !updateblock && lvl != 0) { - /* upsample */ - DerivedMesh *lowdm, *cddm, *highdm; - CCGElem **highGridData, **lowGridData, **subGridData; - CCGKey highGridKey, lowGridKey; - CCGSubSurf *ss; - int i, numGrids, highGridSize; - const bool has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK); - - /* create subsurf DM from original mesh at high level */ - cddm = CDDM_from_mesh(me); - DM_set_only_copy(cddm, &CD_MASK_BAREMESH); - highdm = subsurf_dm_create_local(NULL, - ob, - cddm, - totlvl, - simple, - 0, - mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, - has_mask, - false, - SUBSURF_IGNORE_SIMPLIFY); - ss = ((CCGDerivedMesh *)highdm)->ss; - - /* create multires DM from original mesh at low level */ - lowdm = multires_dm_create_local( - scene, ob, cddm, lvl, lvl, simple, has_mask, MULTIRES_IGNORE_SIMPLIFY); - BLI_assert(lowdm != cddm); - cddm->release(cddm); - - /* copy subsurf grids and replace them with low displaced grids */ - numGrids = highdm->getNumGrids(highdm); - highGridSize = highdm->getGridSize(highdm); - highGridData = highdm->getGridData(highdm); - highdm->getGridKey(highdm, &highGridKey); - lowGridData = lowdm->getGridData(lowdm); - lowdm->getGridKey(lowdm, &lowGridKey); - - subGridData = MEM_calloc_arrayN(numGrids, sizeof(float *), "subGridData*"); - - for (i = 0; i < numGrids; i++) { - /* backup subsurf grids */ - subGridData[i] = MEM_calloc_arrayN( - highGridKey.elem_size, highGridSize * highGridSize, "subGridData"); - memcpy(subGridData[i], highGridData[i], highGridKey.elem_size * highGridSize * highGridSize); - - /* overwrite with current displaced grids */ - multires_copy_dm_grid(highGridData[i], lowGridData[i], &highGridKey, &lowGridKey); - } - - /* low lower level dm no longer needed at this point */ - lowdm->release(lowdm); - - /* subsurf higher levels again with displaced data */ - ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0); - ccgSubSurf_updateLevels(ss, lvl, NULL, 0); - - /* reallocate displacements */ - multires_reallocate_mdisps(me->totloop, mdisps, totlvl); - - /* compute displacements */ - multiresModifier_disp_run(highdm, me, NULL, CALC_DISPLACEMENTS, subGridData, totlvl); - - /* free */ - highdm->release(highdm); - for (i = 0; i < numGrids; i++) { - MEM_freeN(subGridData[i]); - } - MEM_freeN(subGridData); - } - else { - /* only reallocate, nothing to upsample */ - multires_reallocate_mdisps(me->totloop, mdisps, totlvl); - } - - multires_set_tot_level(ob, mmd, totlvl); -} - -void multiresModifier_subdivide_legacy( - MultiresModifierData *mmd, Scene *scene, Object *ob, int updateblock, int simple) -{ - multires_subdivide_legacy(mmd, scene, ob, mmd->totlvl + 1, updateblock, simple); -} - static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3]) { if (axis == 0) { @@ -1449,9 +1303,6 @@ DerivedMesh *multires_make_derived_from_derived( return result; } -/**** Old Multires code **** - ***************************/ - /* Adapted from sculptmode.c */ void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v) { @@ -1506,723 +1357,6 @@ void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, add_v3_v3v3(out, d2[0], d2[1]); } -static void old_mdisps_rotate( - int S, int UNUSED(newside), int oldside, int x, int y, float *u, float *v) -{ - float offset = oldside * 0.5f - 0.5f; - - if (S == 1) { - *u = offset + x; - *v = offset - y; - } - if (S == 2) { - *u = offset + y; - *v = offset + x; - } - if (S == 3) { - *u = offset - x; - *v = offset + y; - } - if (S == 0) { - *u = offset - y; - *v = offset - x; - } -} - -static void old_mdisps_convert(MFace *mface, MDisps *mdisp) -{ - int newlvl = log(sqrt(mdisp->totdisp) - 1) / M_LN2; - int oldlvl = newlvl + 1; - int oldside = multires_side_tot[oldlvl]; - int newside = multires_side_tot[newlvl]; - int nvert = (mface->v4) ? 4 : 3; - int newtotdisp = multires_grid_tot[newlvl] * nvert; - int x, y, S; - float(*disps)[3], (*out)[3], u = 0.0f, v = 0.0f; /* Quite gcc barking. */ - - disps = MEM_calloc_arrayN(newtotdisp, sizeof(float[3]), "multires disps"); - - out = disps; - for (S = 0; S < nvert; S++) { - for (y = 0; y < newside; y++) { - for (x = 0; x < newside; x++, out++) { - old_mdisps_rotate(S, newside, oldside, x, y, &u, &v); - old_mdisps_bilinear(*out, mdisp->disps, oldside, u, v); - - if (S == 1) { - (*out)[1] = -(*out)[1]; - } - else if (S == 2) { - SWAP(float, (*out)[0], (*out)[1]); - } - else if (S == 3) { - (*out)[0] = -(*out)[0]; - } - else if (S == 0) { - SWAP(float, (*out)[0], (*out)[1]); - (*out)[0] = -(*out)[0]; - (*out)[1] = -(*out)[1]; - } - } - } - } - - MEM_freeN(mdisp->disps); - - mdisp->totdisp = newtotdisp; - mdisp->level = newlvl; - mdisp->disps = disps; -} - -void multires_load_old_250(Mesh *me) -{ - MDisps *mdisps, *mdisps2; - MFace *mf; - int i, j, k; - - mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS); - - if (mdisps) { - for (i = 0; i < me->totface; i++) { - if (mdisps[i].totdisp) { - old_mdisps_convert(&me->mface[i], &mdisps[i]); - } - } - - CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop); - mdisps2 = CustomData_get_layer(&me->ldata, CD_MDISPS); - - k = 0; - mf = me->mface; - for (i = 0; i < me->totface; i++, mf++) { - int nvert = mf->v4 ? 4 : 3; - int totdisp = mdisps[i].totdisp / nvert; - - for (j = 0; j < nvert; j++, k++) { - mdisps2[k].disps = MEM_calloc_arrayN( - totdisp, sizeof(float[3]), "multires disp in conversion"); - mdisps2[k].totdisp = totdisp; - mdisps2[k].level = mdisps[i].level; - memcpy(mdisps2[k].disps, mdisps[i].disps + totdisp * j, totdisp); - } - } - } -} - -/* Does not actually free lvl itself */ -static void multires_free_level(MultiresLevel *lvl) -{ - if (lvl) { - if (lvl->faces) { - MEM_freeN(lvl->faces); - } - if (lvl->edges) { - MEM_freeN(lvl->edges); - } - if (lvl->colfaces) { - MEM_freeN(lvl->colfaces); - } - } -} - -void multires_free(Multires *mr) -{ - if (mr) { - MultiresLevel *lvl = mr->levels.first; - - /* Free the first-level data */ - if (lvl) { - CustomData_free(&mr->vdata, lvl->totvert); - CustomData_free(&mr->fdata, lvl->totface); - if (mr->edge_flags) { - MEM_freeN(mr->edge_flags); - } - if (mr->edge_creases) { - MEM_freeN(mr->edge_creases); - } - } - - while (lvl) { - multires_free_level(lvl); - lvl = lvl->next; - } - - /* mr->verts may be NULL when loading old files, - * see direct_link_mesh() in readfile.c, and T43560. */ - MEM_SAFE_FREE(mr->verts); - - BLI_freelistN(&mr->levels); - - MEM_freeN(mr); - } -} - -typedef struct IndexNode { - struct IndexNode *next, *prev; - int index; -} IndexNode; - -static void create_old_vert_face_map(ListBase **map, - IndexNode **mem, - const MultiresFace *mface, - const int totvert, - const int totface) -{ - int i, j; - IndexNode *node = NULL; - - (*map) = MEM_calloc_arrayN(totvert, sizeof(ListBase), "vert face map"); - (*mem) = MEM_calloc_arrayN(totface, sizeof(IndexNode[4]), "vert face map mem"); - node = *mem; - - /* Find the users */ - for (i = 0; i < totface; i++) { - for (j = 0; j < (mface[i].v[3] ? 4 : 3); j++, node++) { - node->index = i; - BLI_addtail(&(*map)[mface[i].v[j]], node); - } - } -} - -static void create_old_vert_edge_map(ListBase **map, - IndexNode **mem, - const MultiresEdge *medge, - const int totvert, - const int totedge) -{ - int i, j; - IndexNode *node = NULL; - - (*map) = MEM_calloc_arrayN(totvert, sizeof(ListBase), "vert edge map"); - (*mem) = MEM_calloc_arrayN(totedge, sizeof(IndexNode[2]), "vert edge map mem"); - node = *mem; - - /* Find the users */ - for (i = 0; i < totedge; i++) { - for (j = 0; j < 2; j++, node++) { - node->index = i; - BLI_addtail(&(*map)[medge[i].v[j]], node); - } - } -} - -static MultiresFace *find_old_face( - ListBase *map, MultiresFace *faces, int v1, int v2, int v3, int v4) -{ - IndexNode *n1; - int v[4], i, j; - - v[0] = v1; - v[1] = v2; - v[2] = v3; - v[3] = v4; - - for (n1 = map[v1].first; n1; n1 = n1->next) { - int fnd[4] = {0, 0, 0, 0}; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - if (v[i] == faces[n1->index].v[j]) { - fnd[i] = 1; - } - } - } - - if (fnd[0] && fnd[1] && fnd[2] && fnd[3]) { - return &faces[n1->index]; - } - } - - return NULL; -} - -static MultiresEdge *find_old_edge(ListBase *map, MultiresEdge *edges, int v1, int v2) -{ - IndexNode *n1, *n2; - - for (n1 = map[v1].first; n1; n1 = n1->next) { - for (n2 = map[v2].first; n2; n2 = n2->next) { - if (n1->index == n2->index) { - return &edges[n1->index]; - } - } - } - - return NULL; -} - -static void multires_load_old_edges( - ListBase **emap, MultiresLevel *lvl, int *vvmap, int dst, int v1, int v2, int mov) -{ - int emid = find_old_edge(emap[2], lvl->edges, v1, v2)->mid; - vvmap[dst + mov] = emid; - - if (lvl->next->next) { - multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v1, emid, mov / 2); - multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v2, emid, -mov / 2); - } -} - -static void multires_load_old_faces(ListBase **fmap, - ListBase **emap, - MultiresLevel *lvl, - int *vvmap, - int dst, - int v1, - int v2, - int v3, - int v4, - int st2, - int st3) -{ - int fmid; - int emid13, emid14, emid23, emid24; - - if (lvl && lvl->next) { - fmid = find_old_face(fmap[1], lvl->faces, v1, v2, v3, v4)->mid; - vvmap[dst] = fmid; - - emid13 = find_old_edge(emap[1], lvl->edges, v1, v3)->mid; - emid14 = find_old_edge(emap[1], lvl->edges, v1, v4)->mid; - emid23 = find_old_edge(emap[1], lvl->edges, v2, v3)->mid; - emid24 = find_old_edge(emap[1], lvl->edges, v2, v4)->mid; - - multires_load_old_faces(fmap + 1, - emap + 1, - lvl->next, - vvmap, - dst + st2 * st3 + st3, - fmid, - v2, - emid23, - emid24, - st2, - st3 / 2); - - multires_load_old_faces(fmap + 1, - emap + 1, - lvl->next, - vvmap, - dst - st2 * st3 + st3, - emid14, - emid24, - fmid, - v4, - st2, - st3 / 2); - - multires_load_old_faces(fmap + 1, - emap + 1, - lvl->next, - vvmap, - dst + st2 * st3 - st3, - emid13, - emid23, - v3, - fmid, - st2, - st3 / 2); - - multires_load_old_faces(fmap + 1, - emap + 1, - lvl->next, - vvmap, - dst - st2 * st3 - st3, - v1, - fmid, - emid13, - emid14, - st2, - st3 / 2); - - if (lvl->next->next) { - multires_load_old_edges(emap, lvl->next, vvmap, dst, emid24, fmid, st3); - multires_load_old_edges(emap, lvl->next, vvmap, dst, emid13, fmid, -st3); - multires_load_old_edges(emap, lvl->next, vvmap, dst, emid14, fmid, -st2 * st3); - multires_load_old_edges(emap, lvl->next, vvmap, dst, emid23, fmid, st2 * st3); - } - } -} - -static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; - CCGSubSurf *ss = ccgdm->ss; - CCGElem *vd; - CCGKey key; - int index; - int totvert, totedge, totface; - int gridSize = ccgSubSurf_getGridSize(ss); - int edgeSize = ccgSubSurf_getEdgeSize(ss); - int i = 0; - - dm->getGridKey(dm, &key); - - totface = ccgSubSurf_getNumFaces(ss); - for (index = 0; index < totface; index++) { - CCGFace *f = ccgdm->faceMap[index].face; - int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - - vd = ccgSubSurf_getFaceCenterData(f); - copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); - i++; - - for (S = 0; S < numVerts; S++) { - for (x = 1; x < gridSize - 1; x++, i++) { - vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x); - copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); - } - } - - for (S = 0; S < numVerts; S++) { - for (y = 1; y < gridSize - 1; y++) { - for (x = 1; x < gridSize - 1; x++, i++) { - vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y); - copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); - } - } - } - } - - totedge = ccgSubSurf_getNumEdges(ss); - for (index = 0; index < totedge; index++) { - CCGEdge *e = ccgdm->edgeMap[index].edge; - int x; - - for (x = 1; x < edgeSize - 1; x++, i++) { - vd = ccgSubSurf_getEdgeData(ss, e, x); - copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); - } - } - - totvert = ccgSubSurf_getNumVerts(ss); - for (index = 0; index < totvert; index++) { - CCGVert *v = ccgdm->vertMap[index].vert; - - vd = ccgSubSurf_getVertData(ss, v); - copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); - i++; - } - - ccgSubSurf_updateToFaces(ss, 0, NULL, 0); -} - -/* Loads a multires object stored in the old Multires struct into the new format */ -static void multires_load_old_dm(DerivedMesh *dm, Mesh *me, int totlvl) -{ - MultiresLevel *lvl, *lvl1; - Multires *mr = me->mr; - MVert *vsrc, *vdst; - unsigned int src, dst; - int st_last = multires_side_tot[totlvl - 1] - 1; - int extedgelen = multires_side_tot[totlvl] - 2; - int *vvmap; // inorder for dst, map to src - int crossedgelen; - int s, x, tottri, totquad; - unsigned int i, j, totvert; - - src = 0; - vsrc = mr->verts; - vdst = dm->getVertArray(dm); - totvert = (unsigned int)dm->getNumVerts(dm); - vvmap = MEM_calloc_arrayN(totvert, sizeof(int), "multires vvmap"); - - if (!vvmap) { - return; - } - - lvl1 = mr->levels.first; - /* Load base verts */ - for (i = 0; i < lvl1->totvert; i++) { - vvmap[totvert - lvl1->totvert + i] = src; - src++; - } - - /* Original edges */ - dst = totvert - lvl1->totvert - extedgelen * lvl1->totedge; - for (i = 0; i < lvl1->totedge; i++) { - int ldst = dst + extedgelen * i; - int lsrc = src; - lvl = lvl1->next; - - for (j = 2; j <= mr->level_count; j++) { - int base = multires_side_tot[totlvl - j + 1] - 2; - int skip = multires_side_tot[totlvl - j + 2] - 1; - int st = multires_side_tot[j - 1] - 1; - - for (x = 0; x < st; x++) { - vvmap[ldst + base + x * skip] = lsrc + st * i + x; - } - - lsrc += lvl->totvert - lvl->prev->totvert; - lvl = lvl->next; - } - } - - /* Center points */ - dst = 0; - for (i = 0; i < lvl1->totface; i++) { - int sides = lvl1->faces[i].v[3] ? 4 : 3; - - vvmap[dst] = src + lvl1->totedge + i; - dst += 1 + sides * (st_last - 1) * st_last; - } - - /* The rest is only for level 3 and up */ - if (lvl1->next && lvl1->next->next) { - ListBase **fmap, **emap; - IndexNode **fmem, **emem; - - /* Face edge cross */ - tottri = totquad = 0; - crossedgelen = multires_side_tot[totlvl - 1] - 2; - dst = 0; - for (i = 0; i < lvl1->totface; i++) { - int sides = lvl1->faces[i].v[3] ? 4 : 3; - - lvl = lvl1->next->next; - dst++; - - for (j = 3; j <= mr->level_count; j++) { - int base = multires_side_tot[totlvl - j + 1] - 2; - int skip = multires_side_tot[totlvl - j + 2] - 1; - int st = pow(2, j - 2); - int st2 = pow(2, j - 3); - int lsrc = lvl->prev->totvert; - - /* Skip exterior edge verts */ - lsrc += lvl1->totedge * st; - - /* Skip earlier face edge crosses */ - lsrc += st2 * (tottri * 3 + totquad * 4); - - for (s = 0; s < sides; s++) { - for (x = 0; x < st2; x++) { - vvmap[dst + crossedgelen * (s + 1) - base - x * skip - 1] = lsrc; - lsrc++; - } - } - - lvl = lvl->next; - } - - dst += sides * (st_last - 1) * st_last; - - if (sides == 4) { - totquad++; - } - else { - tottri++; - } - } - - /* calculate vert to edge/face maps for each level (except the last) */ - fmap = MEM_calloc_arrayN((mr->level_count - 1), sizeof(ListBase *), "multires fmap"); - emap = MEM_calloc_arrayN((mr->level_count - 1), sizeof(ListBase *), "multires emap"); - fmem = MEM_calloc_arrayN((mr->level_count - 1), sizeof(IndexNode *), "multires fmem"); - emem = MEM_calloc_arrayN((mr->level_count - 1), sizeof(IndexNode *), "multires emem"); - lvl = lvl1; - for (i = 0; i < (unsigned int)mr->level_count - 1; i++) { - create_old_vert_face_map(fmap + i, fmem + i, lvl->faces, lvl->totvert, lvl->totface); - create_old_vert_edge_map(emap + i, emem + i, lvl->edges, lvl->totvert, lvl->totedge); - lvl = lvl->next; - } - - /* Interior face verts */ - /* lvl = lvl1->next->next; */ /* UNUSED */ - dst = 0; - for (j = 0; j < lvl1->totface; j++) { - int sides = lvl1->faces[j].v[3] ? 4 : 3; - int ldst = dst + 1 + sides * (st_last - 1); - - for (s = 0; s < sides; s++) { - int st2 = multires_side_tot[totlvl - 1] - 2; - int st3 = multires_side_tot[totlvl - 2] - 2; - int st4 = st3 == 0 ? 1 : (st3 + 1) / 2; - int mid = ldst + st2 * st3 + st3; - int cv = lvl1->faces[j].v[s]; - int nv = lvl1->faces[j].v[s == sides - 1 ? 0 : s + 1]; - int pv = lvl1->faces[j].v[s == 0 ? sides - 1 : s - 1]; - - multires_load_old_faces(fmap, - emap, - lvl1->next, - vvmap, - mid, - vvmap[dst], - cv, - find_old_edge(emap[0], lvl1->edges, pv, cv)->mid, - find_old_edge(emap[0], lvl1->edges, cv, nv)->mid, - st2, - st4); - - ldst += (st_last - 1) * (st_last - 1); - } - - dst = ldst; - } - - /*lvl = lvl->next;*/ /*UNUSED*/ - - for (i = 0; i < (unsigned int)(mr->level_count - 1); i++) { - MEM_freeN(fmap[i]); - MEM_freeN(fmem[i]); - MEM_freeN(emap[i]); - MEM_freeN(emem[i]); - } - - MEM_freeN(fmap); - MEM_freeN(emap); - MEM_freeN(fmem); - MEM_freeN(emem); - } - - /* Transfer verts */ - for (i = 0; i < totvert; i++) { - copy_v3_v3(vdst[i].co, vsrc[vvmap[i]].co); - } - - MEM_freeN(vvmap); - - multires_mvert_to_ss(dm, vdst); -} - -/* Copy the first-level vcol data to the mesh, if it exists */ -/* Warning: higher-level vcol data will be lost */ -static void multires_load_old_vcols(Mesh *me) -{ - MultiresLevel *lvl; - MultiresColFace *colface; - MCol *mcol; - int i, j; - - if (!(lvl = me->mr->levels.first)) { - return; - } - - if (!(colface = lvl->colfaces)) { - return; - } - - /* older multires format never supported multiple vcol layers, - * so we can assume the active vcol layer is the correct one */ - if (!(mcol = CustomData_get_layer(&me->fdata, CD_MCOL))) { - return; - } - - for (i = 0; i < me->totface; i++) { - for (j = 0; j < 4; j++) { - mcol[i * 4 + j].a = colface[i].col[j].a; - mcol[i * 4 + j].r = colface[i].col[j].r; - mcol[i * 4 + j].g = colface[i].col[j].g; - mcol[i * 4 + j].b = colface[i].col[j].b; - } - } -} - -/* Copy the first-level face-flag data to the mesh */ -static void multires_load_old_face_flags(Mesh *me) -{ - MultiresLevel *lvl; - MultiresFace *faces; - int i; - - if (!(lvl = me->mr->levels.first)) { - return; - } - - if (!(faces = lvl->faces)) { - return; - } - - for (i = 0; i < me->totface; i++) { - me->mface[i].flag = faces[i].flag; - } -} - -void multires_load_old(Object *ob, Mesh *me) -{ - MultiresLevel *lvl; - ModifierData *md; - MultiresModifierData *mmd; - DerivedMesh *dm, *orig; - CustomDataLayer *l; - int i; - - /* Load original level into the mesh */ - lvl = me->mr->levels.first; - CustomData_free_layers(&me->vdata, CD_MVERT, lvl->totvert); - CustomData_free_layers(&me->edata, CD_MEDGE, lvl->totedge); - CustomData_free_layers(&me->fdata, CD_MFACE, lvl->totface); - me->totvert = lvl->totvert; - me->totedge = lvl->totedge; - me->totface = lvl->totface; - me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); - me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge); - me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); - memcpy(me->mvert, me->mr->verts, sizeof(MVert) * me->totvert); - for (i = 0; i < me->totedge; i++) { - me->medge[i].v1 = lvl->edges[i].v[0]; - me->medge[i].v2 = lvl->edges[i].v[1]; - } - for (i = 0; i < me->totface; i++) { - me->mface[i].v1 = lvl->faces[i].v[0]; - me->mface[i].v2 = lvl->faces[i].v[1]; - me->mface[i].v3 = lvl->faces[i].v[2]; - me->mface[i].v4 = lvl->faces[i].v[3]; - me->mface[i].mat_nr = lvl->faces[i].mat_nr; - } - - /* Copy the first-level data to the mesh */ - /* XXX We must do this before converting tessfaces to polys/lopps! */ - for (i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; i++, l++) { - CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert); - } - for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; i++, l++) { - CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface); - } - CustomData_reset(&me->mr->vdata); - CustomData_reset(&me->mr->fdata); - - multires_load_old_vcols(me); - multires_load_old_face_flags(me); - - /* multiresModifier_subdivide_legacy (actually, multires_subdivide_legacy) expects polys, not - * tessfaces! */ - BKE_mesh_convert_mfaces_to_mpolys(me); - - /* Add a multires modifier to the object */ - md = ob->modifiers.first; - while (md && BKE_modifier_get_info(md->type)->type == eModifierTypeType_OnlyDeform) { - md = md->next; - } - mmd = (MultiresModifierData *)BKE_modifier_new(eModifierType_Multires); - BLI_insertlinkbefore(&ob->modifiers, md, mmd); - - for (i = 0; i < me->mr->level_count - 1; i++) { - multiresModifier_subdivide_legacy(mmd, NULL, ob, 1, 0); - } - - mmd->lvl = mmd->totlvl; - orig = CDDM_from_mesh(me); - /* XXX We *must* alloc paint mask here, else we have some kind of mismatch in - * multires_modifier_update_mdisps() (called by dm->release(dm)), which always creates the - * reference subsurfed dm with this option, before calling multiresModifier_disp_run(), - * which implicitly expects both subsurfs from its first dm and oldGridData parameters to - * be of the same "format"! */ - dm = multires_make_derived_from_derived(orig, mmd, NULL, ob, 0); - - multires_load_old_dm(dm, me, mmd->totlvl + 1); - - multires_dm_mark_as_modified(dm, MULTIRES_COORDS_MODIFIED); - dm->release(dm); - orig->release(orig); - - /* Remove the old multires */ - multires_free(me->mr); - me->mr = NULL; -} - /* If 'ob_src' and 'ob_dst' both have multires modifiers, synchronize them * such that 'ob_dst' has the same total number of levels as 'ob_src'. */ void multiresModifier_sync_levels_ex(Object *ob_dst, diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 0c9ee61ca19..ae39b200b56 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -1548,8 +1548,8 @@ void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object ssmd.shrinkMode = MOD_SHRINKWRAP_ON_SURFACE; ssmd.shrinkOpts = MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR | MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR; ssmd.keepDist = 0.0f; - - /* Tolerance value to prevent artifacts on sharp edges of a mesh. + + /* Tolerance value to prevent artifacts on sharp edges of a mesh. * This constant and based on experimenting with different values. */ const float projLimitTolerance = 5.0f; ssmd.projLimit = target_me->remesh_voxel_size * projLimitTolerance; diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc index ac3662284d0..60439f27b01 100644 --- a/source/blender/blenlib/intern/delaunay_2d.cc +++ b/source/blender/blenlib/intern/delaunay_2d.cc @@ -1308,8 +1308,8 @@ template<typename T> inline int tri_orient(const SymEdge<T> *t) * For case (a), 'vert' will be the vertex, and lambda will be 0, and 'in' will be the #SymEdge * from 'vert' that has as face the one that you go through to get to this vertex. If you go * exactly along an edge then we set 'in' to NULL, since it won't be needed. The first crossing - * will have 'in' = NULL. We set 'out' to the #SymEdge that has the face we go through to get to the - * next crossing, or, if the next crossing is a case (a), then it is the edge that goes to that + * will have 'in' = NULL. We set 'out' to the #SymEdge that has the face we go through to get to + * the next crossing, or, if the next crossing is a case (a), then it is the edge that goes to that * next vertex. 'out' will be NULL for the last one. * * For case (b), vert will be NULL at first, and later filled in with the created split vertex, diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 5046ee6aab1..f7592308023 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -799,20 +799,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) // BLI_freelistN(&pidlist); - if (ob->type == OB_MESH) { - Mesh *me = blo_do_versions_newlibadr(fd, lib, ob->data); - void *olddata = ob->data; - ob->data = me; - - /* XXX - library meshes crash on loading most yoFrankie levels, - * the multires pointer gets invalid - Campbell */ - if (me && me->id.lib == NULL && me->mr && me->mr->level_count > 1) { - multires_load_old(ob, me); - } - - ob->data = olddata; - } - if (ob->totcol && ob->matbits == NULL) { int a; @@ -1152,7 +1138,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if (bmain->versionfile == 250 && bmain->subversionfile > 1) { for (me = bmain->meshes.first; me; me = me->id.next) { - multires_load_old_250(me); + CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface); } for (ob = bmain->objects.first; ob; ob = ob->id.next) { diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index 2daa1d48f47..00085cb7d59 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -885,18 +885,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } } - /** - * Versioning code until next subversion bump goes here. - * - * \note Be sure to check when bumping the version: - * - "versioning_userdef.c", #blo_do_versions_userdef - * - "versioning_userdef.c", #do_versions_theme - * - * \note Keep this message at the bottom of the function. - */ - { - /* Keep this block, even when empty. */ - + if (!MAIN_VERSION_ATLEAST(bmain, 291, 9)) { /* Remove options of legacy UV/Image editor */ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { @@ -925,4 +914,17 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + /** + * Versioning code until next subversion bump goes here. + * + * \note Be sure to check when bumping the version: + * - "versioning_userdef.c", #blo_do_versions_userdef + * - "versioning_userdef.c", #do_versions_theme + * + * \note Keep this message at the bottom of the function. + */ + { + /* Keep this block, even when empty. */ + } } diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 4acf98cc58b..9d858da266d 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -1959,7 +1959,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) Light *la; Material *ma; ParticleSettings *part; - Mesh *me; bNodeTree *ntree; Tex *tex; ModifierData *md; @@ -2074,23 +2073,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } } - /* Copy over old per-level multires vertex data - * into a single vertex array in struct Multires */ - for (me = bmain->meshes.first; me; me = me->id.next) { - if (me->mr && !me->mr->verts) { - MultiresLevel *lvl = me->mr->levels.last; - if (lvl) { - me->mr->verts = lvl->verts; - lvl->verts = NULL; - /* Don't need the other vert arrays */ - for (lvl = lvl->prev; lvl; lvl = lvl->prev) { - MEM_freeN(lvl->verts); - lvl->verts = NULL; - } - } - } - } - if (bmain->versionfile != 245 || bmain->subversionfile < 1) { for (la = bmain->lights.first; la; la = la->id.next) { la->falloff_type = LA_FALLOFF_INVLINEAR; diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index e81735c698d..6b6d226bd90 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -242,6 +242,10 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme) copy_v3_v3_uchar(btheme->space_node.grid, btheme->space_node.back); } + if (!USER_VERSION_ATLEAST(291, 9)) { + FROM_DEFAULT_V4_UCHAR(space_graph.vertex_active); + } + /** * Versioning code until next subversion bump goes here. * @@ -253,8 +257,6 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme) */ { /* Keep this block, even when empty. */ - - FROM_DEFAULT_V4_UCHAR(space_graph.vertex_active); } #undef FROM_DEFAULT_V4_UCHAR diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index d5ebc73dc1e..df5e7aadc64 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -2343,60 +2343,60 @@ void bmesh_kernel_vert_separate( BLI_assert(!BM_ELEM_API_FLAG_TEST(e_iter, EDGE_VISIT)); BM_ELEM_API_FLAG_ENABLE(e_iter, EDGE_VISIT); } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first); - } - - while (true) { - /* Considering only edges and faces incident on vertex v, walk - * the edges & collect in the 'edges' list for splitting */ - BMEdge *e = v->e; - BM_ELEM_API_FLAG_DISABLE(e, EDGE_VISIT); + while (true) { + /* Considering only edges and faces incident on vertex v, walk + * the edges & collect in the 'edges' list for splitting */ - do { - BLI_assert(!BM_ELEM_API_FLAG_TEST(e, EDGE_VISIT)); - BLI_SMALLSTACK_PUSH(edges, e); - edges_found += 1; + BMEdge *e = v->e; + BM_ELEM_API_FLAG_DISABLE(e, EDGE_VISIT); - if (e->l) { - BMLoop *l_iter, *l_first; - l_iter = l_first = e->l; - do { - BMLoop *l_adjacent = (l_iter->v == v) ? l_iter->prev : l_iter->next; - BLI_assert(BM_vert_in_edge(l_adjacent->e, v)); - if (BM_ELEM_API_FLAG_TEST(l_adjacent->e, EDGE_VISIT)) { - BM_ELEM_API_FLAG_DISABLE(l_adjacent->e, EDGE_VISIT); - BLI_SMALLSTACK_PUSH(edges_search, l_adjacent->e); - } - } while ((l_iter = l_iter->radial_next) != l_first); - } - } while ((e = BLI_SMALLSTACK_POP(edges_search))); + do { + BLI_assert(!BM_ELEM_API_FLAG_TEST(e, EDGE_VISIT)); + BLI_SMALLSTACK_PUSH(edges, e); + edges_found += 1; + + if (e->l) { + BMLoop *l_iter, *l_first; + l_iter = l_first = e->l; + do { + BMLoop *l_adjacent = (l_iter->v == v) ? l_iter->prev : l_iter->next; + BLI_assert(BM_vert_in_edge(l_adjacent->e, v)); + if (BM_ELEM_API_FLAG_TEST(l_adjacent->e, EDGE_VISIT)) { + BM_ELEM_API_FLAG_DISABLE(l_adjacent->e, EDGE_VISIT); + BLI_SMALLSTACK_PUSH(edges_search, l_adjacent->e); + } + } while ((l_iter = l_iter->radial_next) != l_first); + } + } while ((e = BLI_SMALLSTACK_POP(edges_search))); - /* now we have all edges connected to 'v->e' */ + /* now we have all edges connected to 'v->e' */ - BLI_assert(edges_found <= v_edges_num); + BLI_assert(edges_found <= v_edges_num); - if (edges_found == v_edges_num) { - /* We're done! The remaining edges in 'edges' form the last fan, - * which can be left as is. - * if 'edges' were alloc'd it'd be freed here. */ - break; - } + if (edges_found == v_edges_num) { + /* We're done! The remaining edges in 'edges' form the last fan, + * which can be left as is. + * if 'edges' were alloc'd it'd be freed here. */ + break; + } - BMVert *v_new; + BMVert *v_new; - v_new = BM_vert_create(bm, v->co, v, BM_CREATE_NOP); - if (copy_select) { - BM_elem_select_copy(bm, v_new, v); - } + v_new = BM_vert_create(bm, v->co, v, BM_CREATE_NOP); + if (copy_select) { + BM_elem_select_copy(bm, v_new, v); + } - while ((e = BLI_SMALLSTACK_POP(edges))) { - bmesh_edge_vert_swap(e, v_new, v); - } + while ((e = BLI_SMALLSTACK_POP(edges))) { + bmesh_edge_vert_swap(e, v_new, v); + } - if (r_vout) { - BLI_SMALLSTACK_PUSH(verts_new, v_new); + if (r_vout) { + BLI_SMALLSTACK_PUSH(verts_new, v_new); + } + verts_num += 1; } - verts_num += 1; } #undef EDGE_VISIT diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index d524f4a0e1e..54dd121952b 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -353,6 +353,8 @@ set(SRC operations/COM_KeyingDespillOperation.h operations/COM_KeyingOperation.cpp operations/COM_KeyingOperation.h + operations/COM_KeyingSetAlphaOperation.cpp + operations/COM_KeyingSetAlphaOperation.h operations/COM_ColorSpillOperation.cpp operations/COM_ColorSpillOperation.h diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index b75d06763b7..a0ccaf0b9da 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -32,7 +32,7 @@ #include "COM_DilateErodeOperation.h" -#include "COM_SetAlphaOperation.h" +#include "COM_KeyingSetAlphaOperation.h" #include "COM_GaussianAlphaXBlurOperation.h" #include "COM_GaussianAlphaYBlurOperation.h" @@ -322,7 +322,7 @@ void KeyingNode::convertToOperations(NodeConverter &converter, } /* set alpha channel to output image */ - SetAlphaOperation *alphaOperation = new SetAlphaOperation(); + KeyingSetAlphaOperation *alphaOperation = new KeyingSetAlphaOperation(); converter.addOperation(alphaOperation); converter.mapInputSocket(inputImage, alphaOperation->getInputSocket(0)); diff --git a/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.cpp b/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.cpp new file mode 100644 index 00000000000..dff88d49e80 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.cpp @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + */ + +#include "COM_KeyingSetAlphaOperation.h" + +KeyingSetAlphaOperation::KeyingSetAlphaOperation() : NodeOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + + this->m_inputColor = NULL; + this->m_inputAlpha = NULL; +} + +void KeyingSetAlphaOperation::initExecution() +{ + this->m_inputColor = getInputSocketReader(0); + this->m_inputAlpha = getInputSocketReader(1); +} + +void KeyingSetAlphaOperation::executePixelSampled(float output[4], + float x, + float y, + PixelSampler sampler) +{ + float color_input[4]; + float alpha_input[4]; + + this->m_inputColor->readSampled(color_input, x, y, sampler); + this->m_inputAlpha->readSampled(alpha_input, x, y, sampler); + + mul_v4_v4fl(output, color_input, alpha_input[0]); +} + +void KeyingSetAlphaOperation::deinitExecution() +{ + this->m_inputColor = NULL; + this->m_inputAlpha = NULL; +} diff --git a/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.h b/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.h new file mode 100644 index 00000000000..b786240f215 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.h @@ -0,0 +1,39 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + */ + +#pragma once + +#include "COM_NodeOperation.h" + +/** + * Operation which is used by keying node to modify image's alpha channels. + * It keeps color properly pre-multiplied. + */ +class KeyingSetAlphaOperation : public NodeOperation { + private: + SocketReader *m_inputColor; + SocketReader *m_inputAlpha; + + public: + KeyingSetAlphaOperation(); + + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + + void initExecution(); + void deinitExecution(); +}; diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl index cad1346609a..db3497bd043 100644 --- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl @@ -105,7 +105,9 @@ void prepare_raycast(vec3 ray_origin, /* If the line is degenerate, make it cover at least one pixel * to not have to handle zero-pixel extent as a special case later */ - ss_step.xy += vec2((dot(ss_step.xy, ss_step.xy) < 0.00001) ? 0.001 : 0.0); + if (dot(ss_step.xy, ss_step.xy) < 0.00001) { + ss_step.xy = vec2(0.0, 0.0001); + } /* Make ss_step cover one pixel. */ ss_step /= max(abs(ss_step.x), abs(ss_step.y)); @@ -173,7 +175,8 @@ vec3 raycast(int index, float iter; for (iter = 1.0; !hit && (ray_time < max_time) && (iter < MAX_STEP); iter++) { /* Minimum stride of 2 because we are using half res minmax zbuffer. */ - float stride = max(1.0, iter * trace_quality) * 2.0; + /* WORKAROUND: Factor is a bit higher than 2 to avoid some banding. To investigate. */ + float stride = max(1.0, iter * trace_quality) * (2.0 + 0.05); float lod = log2(stride * 0.5 * trace_quality) * lod_fac; ray_time += stride; @@ -234,9 +237,10 @@ vec3 raycast(int index, #endif } - if (discard_backface) { - /* Discard backface hits */ - hit = hit && (prev_delta > 0.0); + /* Discard backface hits. Only do this if the ray traveled enough to avoid loosing intricate + * contact reflections. This is only used for SSReflections. */ + if (discard_backface && prev_delta < 0.0 && curr_time > 4.1) { + hit = false; } /* Reject hit if background. */ diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c index bcdd0f9e3dc..bd97fd8a413 100644 --- a/source/blender/draw/engines/external/external_engine.c +++ b/source/blender/draw/engines/external/external_engine.c @@ -36,6 +36,7 @@ #include "GPU_matrix.h" #include "GPU_shader.h" +#include "GPU_state.h" #include "GPU_viewport.h" #include "external_engine.h" /* own include */ @@ -243,6 +244,8 @@ static void external_draw_scene_do(void *vedata) type = rv3d->render_engine->type; type->view_draw(rv3d->render_engine, draw_ctx->evil_C, draw_ctx->depsgraph); + GPU_bgl_end(); + GPU_matrix_pop(); GPU_matrix_pop_projection(); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 85d86849140..49c75e0b4a1 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -476,19 +476,15 @@ static void keyIndex_switchDirection(EditNurb *editnurb, Nurb *nu) static void switch_keys_direction(Curve *cu, Nurb *actnu) { - KeyBlock *currkey; EditNurb *editnurb = cu->editnurb; ListBase *nubase = &editnurb->nurbs; - Nurb *nu; float *fp; int a; - currkey = cu->key->block.first; - while (currkey) { + LISTBASE_FOREACH (KeyBlock *, currkey, &cu->key->block) { fp = currkey->data; - nu = nubase->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nubase) { if (nu->bezt) { BezTriple *bezt = nu->bezt; a = nu->pntsu; @@ -522,11 +518,7 @@ static void switch_keys_direction(Curve *cu, Nurb *actnu) fp += a * KEYELEM_FLOAT_LEN_BPOINT; } } - - nu = nu->next; } - - currkey = currkey->next; } } @@ -583,13 +575,11 @@ static void bezt_to_key(BezTriple *bezt, float *key) static void calc_keyHandles(ListBase *nurb, float *key) { - Nurb *nu; int a; float *fp = key; BezTriple *bezt; - nu = nurb->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nurb) { if (nu->bezt) { BezTriple *prevp, *nextp; BezTriple cur, prev, next; @@ -649,8 +639,6 @@ static void calc_keyHandles(ListBase *nurb, float *key) a = nu->pntsu * nu->pntsv; fp += a * KEYELEM_FLOAT_LEN_BPOINT; } - - nu = nu->next; } } @@ -666,7 +654,7 @@ static void calc_shapeKeys(Object *obedit, ListBase *newnurbs) KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1); BezTriple *bezt, *oldbezt; BPoint *bp, *oldbp; - Nurb *nu, *newnu; + Nurb *newnu; int totvert = BKE_keyblock_curve_element_count(&editnurb->nurbs); float(*ofs)[3] = NULL; @@ -678,8 +666,8 @@ static void calc_shapeKeys(Object *obedit, ListBase *newnurbs) int totvec = 0; /* Calculate needed memory to store offset */ - nu = editnurb->nurbs.first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { + if (nu->bezt) { /* Three vects to store handles and one for tilt. */ totvec += nu->pntsu * 4; @@ -687,14 +675,11 @@ static void calc_shapeKeys(Object *obedit, ListBase *newnurbs) else { totvec += 2 * nu->pntsu * nu->pntsv; } - - nu = nu->next; } ofs = MEM_callocN(sizeof(float[3]) * totvec, "currkey->data"); - nu = editnurb->nurbs.first; i = 0; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { if (nu->bezt) { bezt = nu->bezt; a = nu->pntsu; @@ -731,8 +716,6 @@ static void calc_shapeKeys(Object *obedit, ListBase *newnurbs) bp++; } } - - nu = nu->next; } } } @@ -745,7 +728,7 @@ static void calc_shapeKeys(Object *obedit, ListBase *newnurbs) float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert, "currkey->data"); ofp = oldkey = currkey->data; - nu = editnurb->nurbs.first; + Nurb *nu = editnurb->nurbs.first; /* We need to restore to original curve into newnurb, *not* editcurve's nurbs. * Otherwise, in case we update obdata *without* leaving editmode (e.g. viewport render), * we would invalidate editcurve. */ @@ -929,11 +912,10 @@ static void fcurve_path_rename(AnimData *adt, ListBase *orig_curves, ListBase *curves) { - FCurve *fcu, *nfcu, *nextfcu; + FCurve *nfcu; int len = strlen(orig_rna_path); - for (fcu = orig_curves->first; fcu; fcu = nextfcu) { - nextfcu = fcu->next; + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, orig_curves) { if (STREQLEN(fcu->rna_path, orig_rna_path, len)) { char *spath, *suffix = fcu->rna_path + len; nfcu = BKE_fcurve_copy(fcu); @@ -977,16 +959,15 @@ static void fcurve_remove(AnimData *adt, ListBase *orig_curves, FCurve *fcu) static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves) { - int nu_index = 0, a, pt_index; + int a, pt_index; EditNurb *editnurb = cu->editnurb; - Nurb *nu; CVKeyIndex *keyIndex; char rna_path[64], orig_rna_path[64]; AnimData *adt = BKE_animdata_from_id(&cu->id); ListBase curves = {NULL, NULL}; - FCurve *fcu, *next; - for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) { + int nu_index = 0; + LISTBASE_FOREACH_INDEX (Nurb *, nu, &editnurb->nurbs, nu_index) { if (nu->bezt) { BezTriple *bezt = nu->bezt; a = nu->pntsu; @@ -1054,9 +1035,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves) /* remove paths for removed control points * need this to make further step with copying non-cv related curves copying * not touching cv's f-curves */ - for (fcu = orig_curves->first; fcu; fcu = next) { - next = fcu->next; - + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, orig_curves) { if (STREQLEN(fcu->rna_path, "splines", 7)) { const char *ch = strchr(fcu->rna_path, '.'); @@ -1066,7 +1045,8 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves) } } - for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) { + nu_index = 0; + LISTBASE_FOREACH_INDEX (Nurb *, nu, &editnurb->nurbs, nu_index) { keyIndex = NULL; if (nu->pntsu) { if (nu->bezt) { @@ -1086,9 +1066,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves) /* the remainders in orig_curves can be copied back (like follow path) */ /* (if it's not path to spline) */ - for (fcu = orig_curves->first; fcu; fcu = next) { - next = fcu->next; - + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, orig_curves) { if (STREQLEN(fcu->rna_path, "splines", 7)) { fcurve_remove(adt, orig_curves, fcu); } @@ -1141,13 +1119,11 @@ static int *init_index_map(Object *obedit, int *r_old_totvert) { Curve *curve = (Curve *)obedit->data; EditNurb *editnurb = curve->editnurb; - Nurb *nu; CVKeyIndex *keyIndex; int *old_to_new_map; - int old_totvert; - int vertex_index; - for (nu = curve->nurb.first, old_totvert = 0; nu != NULL; nu = nu->next) { + int old_totvert = 0; + LISTBASE_FOREACH (Nurb *, nu, &curve->nurb) { if (nu->bezt) { old_totvert += nu->pntsu * 3; } @@ -1161,7 +1137,8 @@ static int *init_index_map(Object *obedit, int *r_old_totvert) old_to_new_map[i] = -1; } - for (nu = editnurb->nurbs.first, vertex_index = 0; nu != NULL; nu = nu->next) { + int vertex_index = 0; + LISTBASE_FOREACH (Nurb *, nu, &curve->nurb) { if (nu->bezt) { BezTriple *bezt = nu->bezt; int a = nu->pntsu; @@ -1205,7 +1182,6 @@ static int *init_index_map(Object *obedit, int *r_old_totvert) static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit) { - Object *object; Curve *curve = (Curve *)obedit->data; EditNurb *editnurb = curve->editnurb; int *old_to_new_map = NULL; @@ -1219,8 +1195,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit) return; } - for (object = bmain->objects.first; object; object = object->id.next) { - ModifierData *md; + LISTBASE_FOREACH (Object *, object, &bmain->objects) { int index; if ((object->parent) && (object->parent->data == curve) && ELEM(object->partype, PARVERT1, PARVERT3)) { @@ -1248,7 +1223,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit) } } if (object->data == curve) { - for (md = object->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Hook) { HookModifierData *hmd = (HookModifierData *)md; int i, j; @@ -1290,13 +1265,12 @@ void ED_curve_editnurb_load(Main *bmain, Object *obedit) if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { Curve *cu = obedit->data; - Nurb *nu, *newnu; ListBase newnurb = {NULL, NULL}, oldnurb = cu->nurb; remap_hooks_and_vertex_parents(bmain, obedit); - for (nu = editnurb->first; nu; nu = nu->next) { - newnu = BKE_nurb_duplicate(nu); + LISTBASE_FOREACH (Nurb *, nu, editnurb) { + Nurb *newnu = BKE_nurb_duplicate(nu); BLI_addtail(&newnurb, newnu); if (nu->type == CU_NURBS) { @@ -1323,7 +1297,6 @@ void ED_curve_editnurb_make(Object *obedit) { Curve *cu = (Curve *)obedit->data; EditNurb *editnurb = cu->editnurb; - Nurb *nu, *newnu; KeyBlock *actkey; if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { @@ -1346,12 +1319,10 @@ void ED_curve_editnurb_make(Object *obedit) cu->editnurb = editnurb; } - nu = cu->nurb.first; - while (nu) { - newnu = BKE_nurb_duplicate(nu); + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { + Nurb *newnu = BKE_nurb_duplicate(nu); BKE_nurb_test_2d(newnu); /* after join, or any other creation of curve */ BLI_addtail(&editnurb->nurbs, newnu); - nu = nu->next; } /* animation could be added in editmode even if there was no animdata in @@ -1722,11 +1693,10 @@ static void rotateflagNurb(ListBase *editnurb, const float rotmat[3][3]) { /* all verts with (flag & 'flag') rotate */ - Nurb *nu; BPoint *bp; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_NURBS) { bp = nu->bp; a = nu->pntsu * nu->pntsv; @@ -1746,12 +1716,11 @@ static void rotateflagNurb(ListBase *editnurb, void ed_editnurb_translate_flag(ListBase *editnurb, uint8_t flag, const float vec[3]) { /* all verts with ('flag' & flag) translate */ - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { a = nu->pntsu; bezt = nu->bezt; @@ -1785,11 +1754,10 @@ void ed_editnurb_translate_flag(ListBase *editnurb, uint8_t flag, const float ve static void weightflagNurb(ListBase *editnurb, short flag, float w) { - Nurb *nu; BPoint *bp; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_NURBS) { a = nu->pntsu * nu->pntsv; bp = nu->bp; @@ -1808,16 +1776,12 @@ static void ed_surf_delete_selected(Object *obedit) { Curve *cu = obedit->data; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu, *next; BPoint *bp, *bpn, *newbp; int a, b, newu, newv; BLI_assert(obedit->type == OB_SURF); - nu = editnurb->first; - while (nu) { - next = nu->next; - + LISTBASE_FOREACH_MUTABLE (Nurb *, nu, editnurb) { /* is entire nurb selected */ bp = nu->bp; a = nu->pntsu * nu->pntsv; @@ -1903,7 +1867,6 @@ static void ed_surf_delete_selected(Object *obedit) } } } - nu = next; } } @@ -1912,15 +1875,12 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d) Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; ListBase *nubase = &editnurb->nurbs; - Nurb *nu, *next; BezTriple *bezt, *bezt1; BPoint *bp, *bp1; int a, type, nuindex = 0; /* first loop, can we remove entire pieces? */ - nu = nubase->first; - while (nu) { - next = nu->next; + LISTBASE_FOREACH_MUTABLE (Nurb *, nu, nubase) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -1981,13 +1941,10 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d) clamp_nurb_order_u(nu); } #endif - nu = next; nuindex++; } /* 2nd loop, delete small pieces: just for curves */ - nu = nubase->first; - while (nu) { - next = nu->next; + LISTBASE_FOREACH_MUTABLE (Nurb *, nu, nubase) { type = 0; if (nu->type == CU_BEZIER) { bezt = nu->bezt; @@ -2047,21 +2004,17 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d) BKE_nurb_order_clamp_u(nu); BKE_nurb_knot_calc_u(nu); } - nu = next; } } /* only for OB_SURF */ bool ed_editnurb_extrude_flag(EditNurb *editnurb, const uint8_t flag) { - Nurb *nu; BPoint *bp, *bpn, *newbp; int a, u, v, len; bool ok = false; - nu = editnurb->nurbs.first; - while (nu) { - + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { if (nu->pntsv == 1) { bp = nu->bp; a = nu->pntsu; @@ -2166,7 +2119,6 @@ bool ed_editnurb_extrude_flag(EditNurb *editnurb, const uint8_t flag) } } } - nu = nu->next; } return ok; @@ -2197,14 +2149,15 @@ static void adduplicateflagNurb( Object *obedit, View3D *v3d, ListBase *newnurb, const uint8_t flag, const bool split) { ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu, *newnu; + Nurb *newnu; BezTriple *bezt, *bezt1; BPoint *bp, *bp1, *bp2, *bp3; Curve *cu = (Curve *)obedit->data; - int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv, i; + int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv; char *usel; - for (i = 0, nu = editnurb->first; nu; i++, nu = nu->next) { + int i = 0; + LISTBASE_FOREACH_INDEX (Nurb *, nu, editnurb, i) { cyclicu = cyclicv = 0; if (nu->type == CU_BEZIER) { for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { @@ -2569,7 +2522,7 @@ static void adduplicateflagNurb( } if (BLI_listbase_is_empty(newnurb) == false) { - for (nu = newnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, newnurb) { if (nu->type == CU_BEZIER) { if (split) { /* recalc first and last */ @@ -2619,10 +2572,9 @@ static int switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) } EditNurb *editnurb = cu->editnurb; - Nurb *nu; - int i; - for (nu = editnurb->nurbs.first, i = 0; nu; nu = nu->next, i++) { + int i = 0; + LISTBASE_FOREACH_INDEX (Nurb *, nu, &editnurb->nurbs, i) { if (ED_curve_nurb_select_check(v3d, nu)) { BKE_nurb_direction_switch(nu); keyData_switchDirectionNurb(cu, nu); @@ -2674,13 +2626,12 @@ static int set_goal_weight_exec(bContext *C, wmOperator *op) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BezTriple *bezt; BPoint *bp; float weight = RNA_float_get(op->ptr, "weight"); int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->bezt) { for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) { if (bezt->f2 & SELECT) { @@ -2741,13 +2692,12 @@ static int set_radius_exec(bContext *C, wmOperator *op) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BezTriple *bezt; BPoint *bp; float radius = RNA_float_get(op->ptr, "radius"); int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->bezt) { for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) { if (bezt->f2 & SELECT) { @@ -2853,12 +2803,11 @@ static int smooth_exec(bContext *C, wmOperator *UNUSED(op)) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; int a, a_end; bool changed = false; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->bezt) { /* duplicate the curve to use in weight calculation */ const BezTriple *bezt_orig = MEM_dupallocN(nu->bezt); @@ -2960,7 +2909,6 @@ void CURVE_OT_smooth(wmOperatorType *ot) static void curve_smooth_value(ListBase *editnurb, const int bezt_offsetof, const int bp_offset) { - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; @@ -2970,7 +2918,7 @@ static void curve_smooth_value(ListBase *editnurb, const int bezt_offsetof, cons int start_sel, end_sel; /* selection indices, inclusive */ float start_rad, end_rad, fac, range; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->bezt) { #define BEZT_VALUE(bezt) (*((float *)((char *)(bezt) + bezt_offsetof))) @@ -3289,12 +3237,11 @@ static int hide_exec(bContext *C, wmOperator *op) } ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BPoint *bp; BezTriple *bezt; int a, sel; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -3385,13 +3332,12 @@ static int reveal_exec(bContext *C, wmOperator *op) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BPoint *bp; BezTriple *bezt; int a; bool changed = false; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { nu->hide = 0; if (nu->type == CU_BEZIER) { bezt = nu->bezt; @@ -3462,7 +3408,6 @@ static void subdividenurb(Object *obedit, View3D *v3d, int number_cuts) { Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; - Nurb *nu; BezTriple *bezt, *beztnew, *beztn; BPoint *bp, *prevbp, *bpnew, *bpn; float vec[15]; @@ -3471,7 +3416,7 @@ static void subdividenurb(Object *obedit, View3D *v3d, int number_cuts) // printf("*** subdivideNurb: entering subdivide\n"); - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { amount = 0; if (nu->type == CU_BEZIER) { BezTriple *nextbezt; @@ -3925,7 +3870,6 @@ static int set_spline_type_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); View3D *v3d = CTX_wm_view3d(C); ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; bool changed = false; bool changed_size = false; const bool use_handles = RNA_boolean_get(op->ptr, "use_handles"); @@ -3936,7 +3880,7 @@ static int set_spline_type_exec(bContext *C, wmOperator *op) continue; } - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (ED_curve_nurb_select_check(v3d, nu)) { const int pntsu_prev = nu->pntsu; const char *err_msg = NULL; @@ -4225,12 +4169,11 @@ static void make_selection_list_nurb(View3D *v3d, ListBase *editnurb, ListBase * { ListBase nbase = {NULL, NULL}; NurbSort *nus, *nustest, *headdo, *taildo; - Nurb *nu; BPoint *bp; float dist, headdist, taildist; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (ED_curve_nurb_select_check(v3d, nu)) { nus = (NurbSort *)MEM_callocN(sizeof(NurbSort), "sort"); @@ -4996,7 +4939,6 @@ bool ed_editnurb_spin( { Curve *cu = (Curve *)obedit->data; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; float cmat[3][3], tmat[3][3], imat[3][3]; float bmat[3][3], rotmat[3][3], scalemat1[3][3], scalemat2[3][3]; float persmat[3][3], persinv[3][3]; @@ -5056,7 +4998,7 @@ bool ed_editnurb_spin( } if (ok) { - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (ED_curve_nurb_select_check(v3d, nu)) { nu->orderv = 4; nu->flagv |= CU_NURB_CYCLIC; @@ -5427,8 +5369,6 @@ static int ed_editcurve_addvert(Curve *cu, View3D *v3d, const float location_init[3]) { - Nurb *nu; - float center[3]; float temp[3]; uint verts_len; @@ -5437,7 +5377,7 @@ static int ed_editcurve_addvert(Curve *cu, zero_v3(center); verts_len = 0; - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { int i; if (nu->type == CU_BEZIER) { BezTriple *bezt; @@ -5472,7 +5412,7 @@ static int ed_editcurve_addvert(Curve *cu, ofs[2] = 0.0f; } - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { if (nu->type == CU_BEZIER) { BezTriple *bezt; for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) { @@ -5511,7 +5451,7 @@ static int ed_editcurve_addvert(Curve *cu, } /* nothing selected: create a new curve */ - nu = BKE_curve_nurb_active_get(cu); + Nurb *nu = BKE_curve_nurb_active_get(cu); if (!nu || nu->type == CU_BEZIER) { Nurb *nurb_new; @@ -5764,8 +5704,7 @@ static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op)) /* First test: curve? */ if (obedit->type != OB_CURVE) { - Nurb *nu; - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { if ((nu->pntsv == 1) && (ED_curve_nurb_select_count(v3d, nu) == 1)) { as_curve = true; break; @@ -5819,13 +5758,12 @@ void CURVE_OT_extrude(wmOperatorType *ot) static bool curve_toggle_cyclic(View3D *v3d, ListBase *editnurb, int direction) { - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; bool changed = false; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->pntsu > 1 || nu->pntsv > 1) { if (nu->type == CU_POLY) { a = nu->pntsu; @@ -5932,10 +5870,9 @@ static int toggle_cyclic_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS ListBase *editnurb = object_editcurve_get(obedit); uiPopupMenu *pup; uiLayout *layout; - Nurb *nu; if (obedit->type == OB_SURF) { - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->pntsu > 1 || nu->pntsv > 1) { if (nu->type == CU_NURBS) { pup = UI_popup_menu_begin(C, IFACE_("Direction"), ICON_NONE); @@ -6064,12 +6001,12 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split) Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; ListBase *nubase = &editnurb->nurbs, newnurb = {NULL, NULL}; - Nurb *nu, *nu1; + Nurb *nu1; BezTriple *bezt, *bezt1, *bezt2; BPoint *bp, *bp1, *bp2; int a, b, starta, enda, cut, cyclicut; - for (nu = nubase->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, nubase) { nu1 = NULL; starta = enda = cut = -1; cyclicut = 0; @@ -6452,7 +6389,7 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split) } } - for (nu = newnurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &newnurb) { if (nu->type == CU_BEZIER) { if (split) { /* deselect for split operator */ @@ -6620,9 +6557,8 @@ static int curve_dissolve_exec(bContext *C, wmOperator *UNUSED(op)) } ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if ((nu->type == CU_BEZIER) && (nu->pntsu > 2)) { uint span_step[2] = {nu->pntsu, nu->pntsu}; uint span_len; @@ -6766,9 +6702,8 @@ static int curve_decimate_exec(bContext *C, wmOperator *op) { ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { if ((nu->pntsu > 2) && nurb_bezt_flag_any(nu, SELECT)) { const int error_target_len = max_ii(2, nu->pntsu * ratio); @@ -6917,7 +6852,6 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob_active = CTX_data_active_object(C); Curve *cu; - Nurb *nu, *newnu; BezTriple *bezt; BPoint *bp; ListBase tempbase; @@ -6955,9 +6889,8 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op) /* watch it: switch order here really goes wrong */ mul_m4_m4m4(cmat, imat, ob_iter->obmat); - nu = cu->nurb.first; - while (nu) { - newnu = BKE_nurb_duplicate(nu); + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { + Nurb *newnu = BKE_nurb_duplicate(nu); if (ob_active->totcol) { /* TODO, merge material lists */ CLAMP(newnu->mat_nr, 0, ob_active->totcol - 1); } @@ -6983,7 +6916,6 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op) bp++; } } - nu = nu->next; } } @@ -7035,12 +6967,11 @@ static int clear_tilt_exec(bContext *C, wmOperator *UNUSED(op)) } ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->bezt) { bezt = nu->bezt; a = nu->pntsu; diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index d54bdf552eb..7d79e748f75 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -4678,7 +4678,9 @@ typedef bool (*GPencilTestFn)(bGPDstroke *gps, const float diff_mat[4][4], void *user_data); -static void gpencil_cutter_dissolve(bGPDlayer *hit_layer, bGPDstroke *hit_stroke) +static void gpencil_cutter_dissolve(bGPDlayer *hit_layer, + bGPDstroke *hit_stroke, + const bool flat_caps) { bGPDspoint *pt = NULL; bGPDspoint *pt1 = NULL; @@ -4722,6 +4724,17 @@ static void gpencil_cutter_dissolve(bGPDlayer *hit_layer, bGPDstroke *hit_stroke pt->flag &= ~GP_SPOINT_TAG; } } + /* If flat caps mode check extremes. */ + if (flat_caps) { + if (hit_stroke->points[0].flag & GP_SPOINT_TAG) { + hit_stroke->caps[0] = GP_STROKE_CAP_FLAT; + } + + if (hit_stroke->points[hit_stroke->totpoints - 1].flag & GP_SPOINT_TAG) { + hit_stroke->caps[1] = GP_STROKE_CAP_FLAT; + } + } + gpencil_stroke_delete_tagged_points( hit_layer->actframe, hit_stroke, gpsn, GP_SPOINT_TAG, false, 1); } @@ -4736,6 +4749,7 @@ static int gpencil_cutter_lasso_select(bContext *C, ScrArea *area = CTX_wm_area(C); ToolSettings *ts = CTX_data_tool_settings(C); const float scale = ts->gp_sculpt.isect_threshold; + const bool flat_caps = RNA_boolean_get(op->ptr, "flat_caps"); bGPDspoint *pt; GP_SpaceConversion gsc = {NULL}; @@ -4810,7 +4824,7 @@ static int gpencil_cutter_lasso_select(bContext *C, } LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) { if (gps->flag & GP_STROKE_SELECT) { - gpencil_cutter_dissolve(gpl, gps); + gpencil_cutter_dissolve(gpl, gps, flat_caps); } } } @@ -4884,6 +4898,8 @@ void GPENCIL_OT_stroke_cutter(wmOperatorType *ot) /* properties */ WM_operator_properties_gesture_lasso(ot); + + RNA_def_boolean(ot->srna, "flat_caps", 0, "Flat Caps", ""); } bool ED_object_gpencil_exit(struct Main *bmain, Object *ob) diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c index e4862617d12..7cf4325d03b 100644 --- a/source/blender/editors/gpencil/gpencil_mesh.c +++ b/source/blender/editors/gpencil/gpencil_mesh.c @@ -25,12 +25,15 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" #include "BLI_math.h" +#include "DNA_anim_types.h" #include "DNA_gpencil_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "BKE_anim_data.h" #include "BKE_context.h" #include "BKE_duplilist.h" #include "BKE_global.h" @@ -86,6 +89,35 @@ typedef struct GpBakeOb { Object *ob; } GpBakeOb; +/* Get list of keyframes used by selected objects. */ +static void animdata_keyframe_list_get(ListBase *ob_list, + const bool only_selected, + GHash *r_keyframes) +{ + /* Loop all objects to get the list of keyframes used. */ + LISTBASE_FOREACH (GpBakeOb *, elem, ob_list) { + Object *ob = elem->ob; + AnimData *adt = BKE_animdata_from_id(&ob->id); + if ((adt == NULL) || (adt->action == NULL)) { + continue; + } + LISTBASE_FOREACH (FCurve *, fcurve, &adt->action->curves) { + int i; + BezTriple *bezt; + for (i = 0, bezt = fcurve->bezt; i < fcurve->totvert; i++, bezt++) { + /* Keyframe number is x value of point. */ + if ((bezt->f2 & SELECT) || (!only_selected)) { + /* Insert only one key for each keyframe number. */ + int key = (int)bezt->vec[1][0]; + if (!BLI_ghash_haskey(r_keyframes, POINTER_FROM_INT(key))) { + BLI_ghash_insert(r_keyframes, POINTER_FROM_INT(key), POINTER_FROM_INT(key)); + } + } + } + } + } +} + static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *list) { GpBakeOb *elem = NULL; @@ -161,13 +193,13 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); Object *ob_gpencil = NULL; - ListBase list = {NULL, NULL}; - gpencil_bake_ob_list(C, depsgraph, scene, &list); + ListBase ob_selected_list = {NULL, NULL}; + gpencil_bake_ob_list(C, depsgraph, scene, &ob_selected_list); /* Cannot check this in poll because the active object changes. */ - if (list.first == NULL) { + if (ob_selected_list.first == NULL) { BKE_report(op->reports, RPT_INFO, "No valid object selected"); - gpencil_bake_free_ob_list(&list); + gpencil_bake_free_ob_list(&ob_selected_list); return OPERATOR_CANCELLED; } @@ -186,6 +218,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) const int thickness = RNA_int_get(op->ptr, "thickness"); const bool use_seams = RNA_boolean_get(op->ptr, "seams"); const bool use_faces = RNA_boolean_get(op->ptr, "faces"); + const bool only_selected = RNA_boolean_get(op->ptr, "only_selected"); const float offset = RNA_float_get(op->ptr, "offset"); const int frame_offset = RNA_int_get(op->ptr, "frame_target") - frame_start; char target[64]; @@ -206,7 +239,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) if ((ob_gpencil == NULL) || (ob_gpencil->type != OB_GPENCIL)) { BKE_report(op->reports, RPT_ERROR, "Target grease pencil object not valid"); - gpencil_bake_free_ob_list(&list); + gpencil_bake_free_ob_list(&ob_selected_list); return OPERATOR_CANCELLED; } @@ -237,6 +270,13 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) /* Loop all frame range. */ int oldframe = (int)DEG_get_ctime(depsgraph); int key = -1; + + /* Get list of keyframes. */ + GHash *keyframe_list = BLI_ghash_int_new(__func__); + if (only_selected) { + animdata_keyframe_list_get(&ob_selected_list, only_selected, keyframe_list); + } + for (int i = frame_start; i < frame_end + 1; i++) { key++; /* Jump if not step limit but include last frame always. */ @@ -244,12 +284,17 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) continue; } + /* Check if frame is in the list of frames to be exported. */ + if ((only_selected) && (!BLI_ghash_haskey(keyframe_list, POINTER_FROM_INT(i)))) { + continue; + } + /* Move scene to new frame. */ CFRA = i; BKE_scene_graph_update_for_newframe(depsgraph); /* Loop all objects in the list. */ - LISTBASE_FOREACH (GpBakeOb *, elem, &list) { + LISTBASE_FOREACH (GpBakeOb *, elem, &ob_selected_list) { Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, elem->ob); /* Generate strokes. */ @@ -270,13 +315,14 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) if (project_type != GP_REPROJECT_KEEP) { LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { bGPDframe *gpf = gpl->actframe; - if (gpf != NULL) { - LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { - if ((gps->flag & GP_STROKE_TAG) == 0) { - ED_gpencil_stroke_reproject( - depsgraph, &gsc, sctx, gpl, gpf, gps, project_type, false); - gps->flag |= GP_STROKE_TAG; - } + if (gpf == NULL) { + continue; + } + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + if ((gps->flag & GP_STROKE_TAG) == 0) { + ED_gpencil_stroke_reproject( + depsgraph, &gsc, sctx, gpl, gpf, gps, project_type, false); + gps->flag |= GP_STROKE_TAG; } } } @@ -314,10 +360,14 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) } /* Free memory. */ - gpencil_bake_free_ob_list(&list); + gpencil_bake_free_ob_list(&ob_selected_list); if (sctx != NULL) { ED_transform_snap_object_context_destroy(sctx); } + /* Free temp hash table. */ + if (keyframe_list != NULL) { + BLI_ghash_free(keyframe_list, NULL, NULL); + } /* notifiers */ if (newob) { @@ -394,6 +444,8 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot) RNA_def_int(ot->srna, "thickness", 1, 1, 100, "Thickness", "", 1, 100); RNA_def_boolean(ot->srna, "seams", 0, "Only Seam Edges", "Convert only seam edges"); RNA_def_boolean(ot->srna, "faces", 1, "Export Faces", "Export faces as filled strokes"); + RNA_def_boolean( + ot->srna, "only_selected", 0, "Only Selected Keyframes", "Convert only selected keyframes"); RNA_def_float_distance( ot->srna, "offset", 0.001f, 0.0, 100.0, "Offset", "Offset strokes from fill", 0.0, 100.00); RNA_def_int(ot->srna, "frame_target", 1, 1, 100000, "Frame Target", "", 1, 100000); diff --git a/source/blender/editors/gpencil/gpencil_trace_utils.c b/source/blender/editors/gpencil/gpencil_trace_utils.c index 05973afe80c..544cb4fef1e 100644 --- a/source/blender/editors/gpencil/gpencil_trace_utils.c +++ b/source/blender/editors/gpencil/gpencil_trace_utils.c @@ -294,7 +294,7 @@ void ED_gpencil_trace_data_to_strokes(Main *bmain, n = path->curve.n; tag = path->curve.tag; c = path->curve.c; - int mat_idx = path->sign == '+' ? 0 : 1; + int mat_idx = path->sign == '+' ? mat_fill_idx : mat_mask_idx; /* Create a new stroke. */ bGPDstroke *gps = BKE_gpencil_stroke_add(gpf, mat_idx, 0, thickness, false); /* Last point that is equals to start point. */ diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 5a45afe9c5a..28a90a26a9d 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -2916,6 +2916,40 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph, } } +/* Helper to get the bigger 2D bound box points. */ +static void gpencil_projected_2d_bound_box(GP_SpaceConversion *gsc, + bGPDstroke *gps, + const float diff_mat[4][4], + float r_min[2], + float r_max[2]) +{ + float bounds[8][2]; + BoundBox bb; + BKE_boundbox_init_from_minmax(&bb, gps->boundbox_min, gps->boundbox_max); + + /* Project 8 vertices in 2D. */ + for (int i = 0; i < 8; i++) { + bGPDspoint pt_dummy, pt_dummy_ps; + copy_v3_v3(&pt_dummy.x, bb.vec[i]); + gpencil_point_to_parent_space(&pt_dummy, diff_mat, &pt_dummy_ps); + gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &bounds[i][0], &bounds[i][1]); + } + + /* Take extremes. */ + INIT_MINMAX2(r_min, r_max); + for (int i = 0; i < 8; i++) { + minmax_v2v2_v2(r_min, r_max, bounds[i]); + } + + /* Ensure the bounding box is oriented to axis. */ + if (r_max[0] < r_min[0]) { + SWAP(float, r_min[0], r_max[0]); + } + if (r_max[1] < r_min[1]) { + SWAP(float, r_min[1], r_max[1]); + } +} + /* Check if the stroke collides with brush. */ bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc, bGPDstroke *gps, @@ -2924,31 +2958,15 @@ bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc, const float diff_mat[4][4]) { const int offset = (int)ceil(sqrt((radius * radius) * 2)); - bGPDspoint pt_dummy, pt_dummy_ps; - float boundbox_min[2] = {0.0f}; - float boundbox_max[2] = {0.0f}; + float boundbox_min[2]; + float boundbox_max[2]; /* Check we have something to use (only for old files). */ if (is_zero_v3(gps->boundbox_min)) { BKE_gpencil_stroke_boundingbox_calc(gps); } - /* Convert bound box to 2d */ - copy_v3_v3(&pt_dummy.x, gps->boundbox_min); - gpencil_point_to_parent_space(&pt_dummy, diff_mat, &pt_dummy_ps); - gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &boundbox_min[0], &boundbox_min[1]); - - copy_v3_v3(&pt_dummy.x, gps->boundbox_max); - gpencil_point_to_parent_space(&pt_dummy, diff_mat, &pt_dummy_ps); - gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &boundbox_max[0], &boundbox_max[1]); - - /* Ensure the bounding box is oriented to axis. */ - if (boundbox_max[0] < boundbox_min[0]) { - SWAP(float, boundbox_min[0], boundbox_max[0]); - } - if (boundbox_max[1] < boundbox_min[1]) { - SWAP(float, boundbox_min[1], boundbox_max[1]); - } + gpencil_projected_2d_bound_box(gsc, gps, diff_mat, boundbox_min, boundbox_max); rcti rect_stroke = {boundbox_min[0], boundbox_max[0], boundbox_min[1], boundbox_max[1]}; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 780ce487550..de3e5f3d5f9 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1244,6 +1244,7 @@ static int parent_noinv_set_exec(bContext *C, wmOperator *op) DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index ef22766cd0c..2193a31f19b 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -248,6 +248,7 @@ typedef struct LassoGestureData { typedef struct LineGestureData { float true_plane[4]; float plane[4]; + bool flip; } LineGestureData; struct SculptGestureOperation; @@ -461,6 +462,8 @@ static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperat line_points[1][0] = RNA_int_get(op->ptr, "xend"); line_points[1][1] = RNA_int_get(op->ptr, "yend"); + sgcontext->line.flip = RNA_boolean_get(op->ptr, "flip"); + float depth_point[3]; float plane_points[3][3]; @@ -481,6 +484,12 @@ static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperat if (!sgcontext->vc.rv3d->is_persp) { mul_v3_fl(normal, -1.0f); } + + /* Apply flip. */ + if (sgcontext->line.flip) { + mul_v3_fl(normal, -1.0f); + } + mul_v3_mat3_m4v3(normal, sgcontext->vc.obact->imat, normal); float plane_point_object_space[3]; mul_v3_m4v3(plane_point_object_space, sgcontext->vc.obact->imat, plane_points[0]); @@ -648,8 +657,7 @@ static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext) SCULPT_undo_push_end(); - ED_region_tag_redraw(sgcontext->vc.region); - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, sgcontext->vc.obact); + SCULPT_tag_update_overlays(C); } /* Face Set Gesture Operation. */ @@ -850,7 +858,7 @@ static EnumPropertyItem prop_trim_operation_types[] = { "JOIN", 0, "Join", - "Join the new mesh as separate geometry, without preforming any boolean operation"}, + "Join the new mesh as separate geometry, without performing any boolean operation"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index adc62b23559..8e7935e821d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3805,20 +3805,33 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); + const bool grab_silhouette = brush->flag2 & BRUSH_GRAB_SILHOUETTE; + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); if (sculpt_brush_test_sq_fn(&test, orig_data.co)) { - const float fade = bstrength * SCULPT_brush_strength_factor(ss, - brush, - orig_data.co, - sqrtf(test.dist), - orig_data.no, - NULL, - vd.mask ? *vd.mask : 0.0f, - vd.index, - thread_id); + float fade = bstrength * SCULPT_brush_strength_factor(ss, + brush, + orig_data.co, + sqrtf(test.dist), + orig_data.no, + NULL, + vd.mask ? *vd.mask : 0.0f, + vd.index, + thread_id); + + if (grab_silhouette) { + float silhouette_test_dir[3]; + normalize_v3_v3(silhouette_test_dir, grab_delta); + if (dot_v3v3(ss->cache->initial_normal, ss->cache->grab_delta) < 0.0f) { + mul_v3_fl(silhouette_test_dir, -1.0f); + } + float vno[3]; + normal_short_to_float_v3(vno, orig_data.no); + fade *= max_ff(dot_v3v3(vno, silhouette_test_dir), 0.0f); + } mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -5666,15 +5679,11 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe /* Check for unsupported features. */ PBVHType type = BKE_pbvh_type(ss->pbvh); if (brush->sculpt_tool == SCULPT_TOOL_PAINT && type != PBVH_FACES) { - if (!U.experimental.use_sculpt_vertex_colors) { - return; - } + return; } if (brush->sculpt_tool == SCULPT_TOOL_SMEAR && type != PBVH_FACES) { - if (!U.experimental.use_sculpt_vertex_colors) { - return; - } + return; } /* Build a list of all nodes that are potentially within the brush's area of influence */ diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c index e764df78c88..8fa20aaae50 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c @@ -192,7 +192,6 @@ static void mask_filter_task_cb(void *__restrict userdata, static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) { - ARegion *region = CTX_wm_region(C); Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); @@ -259,8 +258,8 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) SCULPT_undo_push_end(); - ED_region_tag_redraw(region); - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + SCULPT_tag_update_overlays(C); + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 0d1efcab125..60ce86740cd 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -1163,6 +1163,15 @@ static void buttons_panel_context_draw(const bContext *C, Panel *panel) first = false; } + + uiLayout *pin_row = uiLayoutRow(row, false); + uiLayoutSetAlignment(pin_row, UI_LAYOUT_ALIGN_RIGHT); + uiItemSpacer(pin_row); + uiLayoutSetEmboss(pin_row, UI_EMBOSS_NONE); + uiItemO(pin_row, + "", + (sbuts->flag & SB_PIN_CONTEXT) ? ICON_PINNED : ICON_UNPINNED, + "BUTTONS_OT_toggle_pin"); } void buttons_context_register(ARegionType *art) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 91653fb7785..7cfd749d013 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -2415,7 +2415,8 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN WM_operator_properties_create_ptr(&ptr, ot); RNA_string_set(&ptr, "directory", sfile->params->dir); RNA_boolean_set(&ptr, "open", true); - /* Enable confirmation prompt, else it's too easy to accidentally create new directories. */ + /* Enable confirmation prompt, else it's too easy + * to accidentally create new directories. */ RNA_boolean_set(&ptr, "confirm", true); if (lastdir) { diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index ff9454cd922..a71dec99e61 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -181,11 +181,11 @@ static void file_panel_execution_buttons_draw(const bContext *C, Panel *panel) if (params->flag & FILE_CHECK_EXISTING) { but_extra_rna_ptr = UI_but_extra_operator_icon_add( - but, "FILE_OT_filenum", WM_OP_EXEC_REGION_WIN, ICON_ADD); - RNA_int_set(but_extra_rna_ptr, "increment", 1); - but_extra_rna_ptr = UI_but_extra_operator_icon_add( but, "FILE_OT_filenum", WM_OP_EXEC_REGION_WIN, ICON_REMOVE); RNA_int_set(but_extra_rna_ptr, "increment", -1); + but_extra_rna_ptr = UI_but_extra_operator_icon_add( + but, "FILE_OT_filenum", WM_OP_EXEC_REGION_WIN, ICON_ADD); + RNA_int_set(but_extra_rna_ptr, "increment", 1); } /* check if this overrides a file and if the operator option is used */ diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 09ccb950c18..5a789ee0b01 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1935,8 +1935,14 @@ static void outliner_mode_toggle_fn(bContext *C, void *tselem_poin, void *UNUSED return; } + /* Check that the the item is actually an object. */ + BLI_assert(tselem->id != NULL && GS(tselem->id->name) == ID_OB); + + Object *ob = (Object *)tselem->id; + const bool object_data_shared = (ob->data == tvc.obact->data); + wmWindow *win = CTX_wm_window(C); - const bool do_extend = win->eventstate->ctrl != 0; + const bool do_extend = win->eventstate->ctrl != 0 && !object_data_shared; outliner_item_mode_toggle(C, &tvc, te, do_extend); } @@ -1947,60 +1953,69 @@ static void outliner_draw_mode_column_toggle(uiBlock *block, TreeStoreElem *tselem, const bool lock_object_modes) { - const int active_mode = tvc->obact->mode; - bool draw_active_icon = true; + if (tselem->type != 0 || te->idcode != ID_OB) { + return; + } - if (tselem->type == 0 && te->idcode == ID_OB) { - Object *ob = (Object *)tselem->id; + Object *ob = (Object *)tselem->id; + Object *ob_active = tvc->obact; - /* When not locking object modes, objects can remain in non-object modes. For modes that do not - * allow multi-object editing, these other objects should still show be viewed as not in the - * mode. Otherwise multiple objects show the same mode icon in the outliner even though only - * one object is actually editable in the mode. */ - if (!lock_object_modes && ob != tvc->obact && !(tvc->ob_edit || tvc->ob_pose)) { - draw_active_icon = false; - } + /* Not all objects support particle systems. */ + if (ob_active->mode == OB_MODE_PARTICLE_EDIT && !psys_get_current(ob)) { + return; + } - if (ob->type == tvc->obact->type) { - int icon; - const char *tip; + /* Only for objects with the same type. */ + if (ob->type != ob_active->type) { + return; + } - if (draw_active_icon && ob->mode == tvc->obact->mode) { - icon = UI_icon_from_object_mode(active_mode); - tip = TIP_("Remove from the current mode"); - } - else { - /* Not all objects support particle systems */ - if (active_mode == OB_MODE_PARTICLE_EDIT && !psys_get_current(ob)) { - return; - } - icon = ICON_DOT; - tip = TIP_( - "Change the object in the current mode\n" - "* Ctrl to add to the current mode"); - } + bool draw_active_icon = ob->mode == ob_active->mode; - uiBut *but = uiDefIconBut(block, - UI_BTYPE_ICON_TOGGLE, - 0, - icon, - 0, - te->ys, - UI_UNIT_X, - UI_UNIT_Y, - NULL, - 0.0, - 0.0, - 0.0, - 0.0, - tip); - UI_but_func_set(but, outliner_mode_toggle_fn, tselem, NULL); - UI_but_flag_enable(but, UI_BUT_DRAG_LOCK); - - if (ID_IS_LINKED(&ob->id)) { - UI_but_disable(but, TIP_("Can't edit external library data")); - } - } + /* When not locking object modes, objects can remain in non-object modes. For modes that do not + * allow multi-object editing, these other objects should still show be viewed as not in the + * mode. Otherwise multiple objects show the same mode icon in the outliner even though only + * one object is actually editable in the mode. */ + if (!lock_object_modes && ob != ob_active && !(tvc->ob_edit || tvc->ob_pose)) { + draw_active_icon = false; + } + + const bool object_data_shared = (ob->data == ob_active->data); + draw_active_icon = draw_active_icon || object_data_shared; + + int icon; + const char *tip; + if (draw_active_icon) { + icon = UI_icon_from_object_mode(ob_active->mode); + tip = object_data_shared ? TIP_("Change the object in the current mode") : + TIP_("Remove from the current mode"); + } + else { + icon = ICON_DOT; + tip = TIP_( + "Change the object in the current mode\n" + "* Ctrl to add to the current mode"); + } + + uiBut *but = uiDefIconBut(block, + UI_BTYPE_ICON_TOGGLE, + 0, + icon, + 0, + te->ys, + UI_UNIT_X, + UI_UNIT_Y, + NULL, + 0.0, + 0.0, + 0.0, + 0.0, + tip); + UI_but_func_set(but, outliner_mode_toggle_fn, tselem, NULL); + UI_but_flag_enable(but, UI_BUT_DRAG_LOCK); + + if (ID_IS_LINKED(&ob->id)) { + UI_but_disable(but, TIP_("Can't edit external library data")); } } diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 3357b0b7346..cbdeb350ba4 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -730,6 +730,9 @@ static void id_local_fn(bContext *C, BKE_main_id_clear_newpoins(bmain); } } + else if (ID_IS_OVERRIDE_LIBRARY_REAL(tselem->id)) { + BKE_lib_override_library_free(&tselem->id->override_library, true); + } } static void object_proxy_to_override_convert_fn(bContext *C, diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp index dbf1c12fb01..3efabbfbdf5 100644 --- a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp +++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp @@ -55,21 +55,14 @@ PyDoc_STRVAR( "Class defining a material.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(line, diffuse, ambient, specular, emission, shininess, priority)\n" "\n" - " Default constructor.\n" + " Creates a :class:`FrsMaterial` using either default constructor,\n" + " copy constructor, or an overloaded constructor\n" "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" - "\n" - " :arg brother: A Material object.\n" + " :arg brother: A Material object to be used as a copy constructor.\n" " :type brother: :class:`Material`\n" - "\n" - ".. method:: __init__(line, diffuse, ambient, specular, emission, shininess, priority)\n" - "\n" - " Builds a Material from its line, diffuse, ambient, specular, emissive\n" - " colors, a shininess coefficient and line color priority.\n" - "\n" " :arg line: The line color.\n" " :type line: :class:`mathutils.Vector`, list or tuple of 4 float values\n" " :arg diffuse: The diffuse color.\n" diff --git a/source/blender/freestyle/intern/python/BPy_Id.cpp b/source/blender/freestyle/intern/python/BPy_Id.cpp index eb0eb661e3d..8f61f7f3e14 100644 --- a/source/blender/freestyle/intern/python/BPy_Id.cpp +++ b/source/blender/freestyle/intern/python/BPy_Id.cpp @@ -46,24 +46,21 @@ int Id_Init(PyObject *module) //------------------------INSTANCE METHODS ---------------------------------- -PyDoc_STRVAR(Id_doc, - "Class for representing an object Id.\n" - "\n" - ".. method:: __init__(first=0, second=0)\n" - "\n" - " Build the Id from two numbers.\n" - "\n" - " :arg first: The first number.\n" - " :type first: int\n" - " :arg second: The second number.\n" - " :type second: int\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" - "\n" - " :arg brother: An Id object.\n" - " :type brother: :class:`Id`"); +PyDoc_STRVAR( + Id_doc, + "Class for representing an object Id.\n" + "\n" + ".. method:: __init__(brother)\n" + " __init__(first=0, second=0)\n" + "\n" + " Build the Id from two numbers or another :class:`Id` using the copy constructor.\n" + "\n" + " :arg brother: An Id object.\n" + " :type brother: :class:`Id`" + " :arg first: The first number.\n" + " :type first: int\n" + " :arg second: The second number.\n" + " :type second: int\n"); static int Id_init(BPy_Id *self, PyObject *args, PyObject *kwds) { diff --git a/source/blender/freestyle/intern/python/BPy_Operators.cpp b/source/blender/freestyle/intern/python/BPy_Operators.cpp index 56f95b8ecbb..1235786d5d3 100644 --- a/source/blender/freestyle/intern/python/BPy_Operators.cpp +++ b/source/blender/freestyle/intern/python/BPy_Operators.cpp @@ -101,6 +101,7 @@ static PyObject *Operators_select(BPy_Operators * /*self*/, PyObject *args, PyOb PyDoc_STRVAR(Operators_chain_doc, ".. staticmethod:: chain(it, pred, modifier)\n" + " chain(it, pred)\n" "\n" " Builds a set of chains from the current set of ViewEdges. Each\n" " ViewEdge of the current list starts a new chain. The chaining\n" @@ -116,28 +117,9 @@ PyDoc_STRVAR(Operators_chain_doc, " :type pred: :class:`UnaryPredicate1D`\n" " :arg modifier: A function that takes a ViewEdge as argument and\n" " that is used to modify the processed ViewEdge state (the\n" - " timestamp incrementation is a typical illustration of such a\n" - " modifier).\n" - " :type modifier: :class:`UnaryFunction1DVoid`\n" - "\n" - ".. staticmethod:: chain(it, pred)\n" - "\n" - " Builds a set of chains from the current set of ViewEdges. Each\n" - " ViewEdge of the current list starts a new chain. The chaining\n" - " operator then iterates over the ViewEdges of the ViewMap using the\n" - " user specified iterator. This operator only iterates using the\n" - " increment operator and is therefore unidirectional. This chaining\n" - " operator is different from the previous one because it doesn't take\n" - " any modifier as argument. Indeed, the time stamp (insuring that a\n" - " ViewEdge is processed one time) is automatically managed in this\n" - " case.\n" - "\n" - " :arg it: The iterator on the ViewEdges of the ViewMap. It contains\n" - " the chaining rule. \n" - " :type it: :class:`ViewEdgeIterator`\n" - " :arg pred: The predicate on the ViewEdge that expresses the\n" - " stopping condition.\n" - " :type pred: :class:`UnaryPredicate1D`"); + " timestamp incrementation is a typical illustration of such a modifier).\n" + " If this argument is not given, the time stamp is automatically managed.\n" + " :type modifier: :class:`UnaryFunction1DVoid`\n"); static PyObject *Operators_chain(BPy_Operators * /*self*/, PyObject *args, PyObject *kwds) { @@ -195,6 +177,7 @@ static PyObject *Operators_chain(BPy_Operators * /*self*/, PyObject *args, PyObj PyDoc_STRVAR(Operators_bidirectional_chain_doc, ".. staticmethod:: bidirectional_chain(it, pred)\n" + " bidirectional_chain(it)\n" "\n" " Builds a set of chains from the current set of ViewEdges. Each\n" " ViewEdge of the current list potentially starts a new chain. The\n" @@ -211,30 +194,10 @@ PyDoc_STRVAR(Operators_bidirectional_chain_doc, " :arg it: The ChainingIterator on the ViewEdges of the ViewMap. It\n" " contains the chaining rule.\n" " :type it: :class:`ChainingIterator`\n" - " :arg pred: The predicate on the ViewEdge that expresses the\n" - " stopping condition.\n" - " :type pred: :class:`UnaryPredicate1D`\n" - "\n" - ".. staticmethod:: bidirectional_chain(it)\n" - "\n" - " The only difference with the above bidirectional chaining algorithm\n" - " is that we don't need to pass a stopping criterion. This might be\n" - " desirable when the stopping criterion is already contained in the\n" - " iterator definition. Builds a set of chains from the current set of\n" - " ViewEdges. Each ViewEdge of the current list potentially starts a new\n" - " chain. The chaining operator then iterates over the ViewEdges of the\n" - " ViewMap using the user specified iterator. This operator iterates\n" - " both using the increment and decrement operators and is therefore\n" - " bidirectional. This operator works with a ChainingIterator which\n" - " contains the chaining rules. It is this last one which can be told to\n" - " chain only edges that belong to the selection or not to process twice\n" - " a ViewEdge during the chaining. Each time a ViewEdge is added to a\n" - " chain, its chaining time stamp is incremented. This allows you to\n" - " keep track of the number of chains to which a ViewEdge belongs to.\n" - "\n" - " :arg it: The ChainingIterator on the ViewEdges of the ViewMap. It\n" - " contains the chaining rule.\n" - " :type it: :class:`ChainingIterator`"); + " :arg pred: The predicate on the ViewEdge that expresses the stopping condition.\n" + " This parameter is optional, you make not want to pass a stopping criterion\n" + " when the stopping criterion is already contained in the iterator definition.\n" + " :type pred: :class:`UnaryPredicate1D`\n"); static PyObject *Operators_bidirectional_chain(BPy_Operators * /*self*/, PyObject *args, @@ -287,44 +250,34 @@ static PyObject *Operators_bidirectional_chain(BPy_Operators * /*self*/, PyDoc_STRVAR(Operators_sequential_split_doc, ".. staticmethod:: sequential_split(starting_pred, stopping_pred, sampling=0.0)\n" + " sequential_split(pred, sampling=0.0)\n" "\n" " Splits each chain of the current set of chains in a sequential way.\n" " The points of each chain are processed (with a specified sampling)\n" - " sequentially. Each time a user specified starting condition is\n" - " verified, a new chain begins and ends as soon as a user-defined\n" - " stopping predicate is verified. This allows chains overlapping rather\n" - " than chains partitioning. The first point of the initial chain is the\n" + " sequentially. The first point of the initial chain is the\n" " first point of one of the resulting chains. The splitting ends when\n" " no more chain can start.\n" "\n" + " .. tip::\n" + "\n" + " By specifiying a starting and stopping predicate allows\n" + " the chains to overlapp rather than chains partitioning.\n" + "\n" " :arg starting_pred: The predicate on a point that expresses the\n" - " starting condition.\n" + " starting condition. Each time this condition is verified, a new chain begins\n" " :type starting_pred: :class:`UnaryPredicate0D`\n" " :arg stopping_pred: The predicate on a point that expresses the\n" - " stopping condition.\n" + " stopping condition. The chain ends as soon as this predicate is verified.\n" " :type stopping_pred: :class:`UnaryPredicate0D`\n" + " :arg pred: The predicate on a point that expresses the splitting condition.\n" + " Each time the condition is verified, the chain is split into two chains.\n" + " The resulting set of chains is a partition of the initial chain\n" + " :type pred: :class:`UnaryPredicate0D`\n" " :arg sampling: The resolution used to sample the chain for the\n" " predicates evaluation. (The chain is not actually resampled;\n" " a virtual point only progresses along the curve using this\n" " resolution.)\n" - " :type sampling: float\n" - "\n" - ".. staticmethod:: sequential_split(pred, sampling=0.0)\n" - "\n" - " Splits each chain of the current set of chains in a sequential way.\n" - " The points of each chain are processed (with a specified sampling)\n" - " sequentially and each time a user specified condition is verified,\n" - " the chain is split into two chains. The resulting set of chains is a\n" - " partition of the initial chain\n" - "\n" - " :arg pred: The predicate on a point that expresses the splitting\n" - " condition.\n" - " :type pred: :class:`UnaryPredicate0D`\n" - " :arg sampling: The resolution used to sample the chain for the\n" - " predicate evaluation. (The chain is not actually resampled; a\n" - " virtual point only progresses along the curve using this\n" - " resolution.)\n" - " :type sampling: float"); + " :type sampling: float\n"); static PyObject *Operators_sequential_split(BPy_Operators * /*self*/, PyObject *args, @@ -389,61 +342,41 @@ static PyObject *Operators_sequential_split(BPy_Operators * /*self*/, Py_RETURN_NONE; } -PyDoc_STRVAR(Operators_recursive_split_doc, - ".. staticmethod:: recursive_split(func, pred_1d, sampling=0.0)\n" - "\n" - " Splits the current set of chains in a recursive way. We process the\n" - " points of each chain (with a specified sampling) to find the point\n" - " minimizing a specified function. The chain is split in two at this\n" - " point and the two new chains are processed in the same way. The\n" - " recursivity level is controlled through a predicate 1D that expresses\n" - " a stopping condition on the chain that is about to be processed.\n" - "\n" - " :arg func: The Unary Function evaluated at each point of the chain.\n" - " The splitting point is the point minimizing this function.\n" - " :type func: :class:`UnaryFunction0DDouble`\n" - " :arg pred_1d: The Unary Predicate expressing the recursivity stopping\n" - " condition. This predicate is evaluated for each curve before it\n" - " actually gets split. If pred_1d(chain) is true, the curve won't be\n" - " split anymore.\n" - " :type pred_1d: :class:`UnaryPredicate1D`\n" - " :arg sampling: The resolution used to sample the chain for the\n" - " predicates evaluation. (The chain is not actually resampled, a\n" - " virtual point only progresses along the curve using this\n" - " resolution.)\n" - " :type sampling: float\n" - "\n" - ".. staticmethod:: recursive_split(func, pred_0d, pred_1d, sampling=0.0)\n" - "\n" - " Splits the current set of chains in a recursive way. We process the\n" - " points of each chain (with a specified sampling) to find the point\n" - " minimizing a specified function. The chain is split in two at this\n" - " point and the two new chains are processed in the same way. The user\n" - " can specify a 0D predicate to make a first selection on the points\n" - " that can potentially be split. A point that doesn't verify the 0D\n" - " predicate won't be candidate in realizing the min. The recursivity\n" - " level is controlled through a predicate 1D that expresses a stopping\n" - " condition on the chain that is about to be processed.\n" - "\n" - " :arg func: The Unary Function evaluated at each point of the chain.\n" - " The splitting point is the point minimizing this function.\n" - " :type func: :class:`UnaryFunction0DDouble`\n" - " :arg pred_0d: The Unary Predicate 0D used to select the candidate\n" - " points where the split can occur. For example, it is very likely\n" - " that would rather have your chain splitting around its middle\n" - " point than around one of its extremities. A 0D predicate working\n" - " on the curvilinear abscissa allows to add this kind of constraints.\n" - " :type pred_0d: :class:`UnaryPredicate0D`\n" - " :arg pred_1d: The Unary Predicate expressing the recursivity stopping\n" - " condition. This predicate is evaluated for each curve before it\n" - " actually gets split. If pred_1d(chain) is true, the curve won't be\n" - " split anymore.\n" - " :type pred_1d: :class:`UnaryPredicate1D`\n" - " :arg sampling: The resolution used to sample the chain for the\n" - " predicates evaluation. (The chain is not actually resampled; a\n" - " virtual point only progresses along the curve using this\n" - " resolution.)\n" - " :type sampling: float"); +PyDoc_STRVAR( + Operators_recursive_split_doc, + ".. staticmethod:: recursive_split(func, pred_1d, sampling=0.0)\n" + " recursive_split(func, pred_0d, pred_1d, sampling=0.0)\n" + "\n" + " Splits the current set of chains in a recursive way. We process the\n" + " points of each chain (with a specified sampling) to find the point\n" + " minimizing a specified function. The chain is split in two at this\n" + " point and the two new chains are processed in the same way. The\n" + " recursivity level is controlled through a predicate 1D that expresses\n" + " a stopping condition on the chain that is about to be processed.\n" + "\n" + " The user can also specify a 0D predicate to make a first selection on the points\n" + " that can potentially be split. A point that doesn't verify the 0D\n" + " predicate won't be candidate in realizing the min.\n" + "\n" + " :arg func: The Unary Function evaluated at each point of the chain.\n" + " The splitting point is the point minimizing this function.\n" + " :type func: :class:`UnaryFunction0DDouble`\n" + " :arg pred_0d: The Unary Predicate 0D used to select the candidate\n" + " points where the split can occur. For example, it is very likely\n" + " that would rather have your chain splitting around its middle\n" + " point than around one of its extremities. A 0D predicate working\n" + " on the curvilinear abscissa allows to add this kind of constraints.\n" + " :type pred_0d: :class:`UnaryPredicate0D`\n" + " :arg pred_1d: The Unary Predicate expressing the recursivity stopping\n" + " condition. This predicate is evaluated for each curve before it\n" + " actually gets split. If pred_1d(chain) is true, the curve won't be\n" + " split anymore.\n" + " :type pred_1d: :class:`UnaryPredicate1D`\n" + " :arg sampling: The resolution used to sample the chain for the\n" + " predicates evaluation. (The chain is not actually resampled; a\n" + " virtual point only progresses along the curve using this\n" + " resolution.)\n" + " :type sampling: float\n"); static PyObject *Operators_recursive_split(BPy_Operators * /*self*/, PyObject *args, diff --git a/source/blender/freestyle/intern/python/BPy_SShape.cpp b/source/blender/freestyle/intern/python/BPy_SShape.cpp index 9712dccfa5e..b1d5f8f4aac 100644 --- a/source/blender/freestyle/intern/python/BPy_SShape.cpp +++ b/source/blender/freestyle/intern/python/BPy_SShape.cpp @@ -50,20 +50,18 @@ int SShape_Init(PyObject *module) /*----------------------SShape methods ----------------------------*/ -PyDoc_STRVAR(SShape_doc, - "Class to define a feature shape. It is the gathering of feature\n" - "elements from an identified input shape.\n" - "\n" - ".. method:: __init__()\n" - "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" - "\n" - " :arg brother: An SShape object.\n" - " :type brother: :class:`SShape`"); +PyDoc_STRVAR( + SShape_doc, + "Class to define a feature shape. It is the gathering of feature\n" + "elements from an identified input shape.\n" + "\n" + ".. method:: __init__()\n" + " __init__(brother)\n" + "\n" + " Creates a :class:`SShape` class using either a default constructor or copy constructor.\n" + "\n" + " :arg brother: An SShape object.\n" + " :type brother: :class:`SShape`"); static int SShape_init(BPy_SShape *self, PyObject *args, PyObject *kwds) { diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp index 214385f74ad..3718fddcf20 100644 --- a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp +++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp @@ -53,20 +53,16 @@ PyDoc_STRVAR(StrokeAttribute_doc, "Vertex.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(red, green, blue, alpha, thickness_right, thickness_left)\n" + " __init__(attribute1, attribute2, t)\n" "\n" - " Default constructor.\n" + " Creates a :class:`StrokeAttribute` object using either a default constructor,\n" + " copy constructor, overloaded constructor, or and interpolation constructor\n" + " to interpolate between two :class:`StrokeAttribute` objects.\n" "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" - "\n" - " :arg brother: A StrokeAttribute object.\n" + " :arg brother: A StrokeAttribute object to be used as a copy constructor.\n" " :type brother: :class:`StrokeAttribute`\n" - "\n" - ".. method:: __init__(red, green, blue, alpha, thickness_right, thickness_left)\n" - "\n" - " Build a stroke vertex attribute from a set of parameters.\n" - "\n" " :arg red: Red component of a stroke color.\n" " :type red: float\n" " :arg green: Green component of a stroke color.\n" @@ -79,12 +75,6 @@ PyDoc_STRVAR(StrokeAttribute_doc, " :type thickness_right: float\n" " :arg thickness_left: Stroke thickness on the left.\n" " :type thickness_left: float\n" - "\n" - ".. method:: __init__(attribute1, attribute2, t)\n" - "\n" - " Interpolation constructor. Build a StrokeAttribute from two\n" - " StrokeAttribute objects and an interpolation parameter.\n" - "\n" " :arg attribute1: The first StrokeAttribute object.\n" " :type attribute1: :class:`StrokeAttribute`\n" " :arg attribute2: The second StrokeAttribute object.\n" diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp index 2adcae13e6d..7d8b5ef6fa9 100644 --- a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp +++ b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp @@ -55,20 +55,14 @@ PyDoc_STRVAR(ViewShape_doc, "and :class:`ViewEdge`) that are issued from the same input shape.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(sshape)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" + " Builds a :class:`ViewShape` using the default constructor,\n" + " copy constructor, or from a :class:`SShape`.\n" "\n" " :arg brother: A ViewShape object.\n" " :type brother: :class:`ViewShape`\n" - "\n" - ".. method:: __init__(sshape)\n" - "\n" - " Builds a ViewShape from an SShape.\n" - "\n" " :arg sshape: An SShape object.\n" " :type sshape: :class:`SShape`"); diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp index 81dd79ff270..7b3571c479f 100644 --- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp @@ -44,40 +44,28 @@ PyDoc_STRVAR(CurvePoint_doc, "given resolution.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(first_vertex, second_vertex, t2d)\n" + " __init__(first_point, second_point, t2d)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" + " Builds a CurvePoint using the default constructor, copy constructor,\n" + " or one of the overloaded constructors. The over loaded constructors\n" + " can either take two :class:`SVertex` or two :class:`CurvePoint`\n" + " objects and an interpolation parameter\n" "\n" " :arg brother: A CurvePoint object.\n" " :type brother: :class:`CurvePoint`\n" - "\n" - ".. method:: __init__(first_vertex, second_vertex, t2d)\n" - "\n" - " Builds a CurvePoint from two SVertex objects and an interpolation parameter.\n" - "\n" " :arg first_vertex: The first SVertex.\n" " :type first_vertex: :class:`SVertex`\n" " :arg second_vertex: The second SVertex.\n" " :type second_vertex: :class:`SVertex`\n" - " :arg t2d: A 2D interpolation parameter used to linearly interpolate\n" - " first_vertex and second_vertex.\n" - " :type t2d: float\n" - "\n" - ".. method:: __init__(first_point, second_point, t2d)\n" - "\n" - " Builds a CurvePoint from two CurvePoint objects and an interpolation\n" - " parameter.\n" - "\n" " :arg first_point: The first CurvePoint.\n" " :type first_point: :class:`CurvePoint`\n" " :arg second_point: The second CurvePoint.\n" " :type second_point: :class:`CurvePoint`\n" - " :arg t2d: The 2D interpolation parameter used to linearly interpolate\n" - " first_point and second_point.\n" - " :type t2d: float"); + " :arg t2d: A 2D interpolation parameter used to linearly interpolate\n" + " first_vertex and second_vertex or first_point and second_point.\n" + " :type t2d: float\n"); static int CurvePoint_init(BPy_CurvePoint *self, PyObject *args, PyObject *kwds) { diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp index c01f1f17000..63725c6b0e8 100644 --- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp @@ -38,20 +38,15 @@ PyDoc_STRVAR(SVertex_doc, "Class to define a vertex of the embedding.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(point_3d, id)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" + " Builds a :class:`SVertex` using the default constructor,\n" + " copy constructor or the overloaded constructor which builds" + " a :class:`SVertex` from 3D coordinates and an Id.\n" "\n" " :arg brother: A SVertex object.\n" " :type brother: :class:`SVertex`\n" - "\n" - ".. method:: __init__(point_3d, id)\n" - "\n" - " Builds a SVertex from 3D coordinates and an Id.\n" - "\n" " :arg point_3d: A three-dimensional vector.\n" " :type point_3d: :class:`mathutils.Vector`\n" " :arg id: An Id object.\n" diff --git a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp index 519bd72db3b..5c1a8f8482f 100644 --- a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp +++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp @@ -40,46 +40,29 @@ PyDoc_STRVAR( "Class to define a stroke vertex.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(first_vertex, second_vertex, t3d)\n" + " __init__(point)\n" + " __init__(svertex)\n" + " __init__(svertex, attribute)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" + " Builds a :class:`StrokeVertex` using the default constructor,\n" + " copy constructor, from 2 :class:`StrokeVertex` and an interpolation parameter,\n" + " from a CurvePoint, from a SVertex, or a :class:`SVertex`" + " and a :class:`StrokeAttribute` object.\n" "\n" " :arg brother: A StrokeVertex object.\n" " :type brother: :class:`StrokeVertex`\n" - "\n" - ".. method:: __init__(first_vertex, second_vertex, t3d)\n" - "\n" - " Build a stroke vertex from 2 stroke vertices and an interpolation\n" - " parameter.\n" - "\n" " :arg first_vertex: The first StrokeVertex.\n" " :type first_vertex: :class:`StrokeVertex`\n" " :arg second_vertex: The second StrokeVertex.\n" " :type second_vertex: :class:`StrokeVertex`\n" " :arg t3d: An interpolation parameter.\n" " :type t3d: float\n" - "\n" - ".. method:: __init__(point)\n" - "\n" - " Build a stroke vertex from a CurvePoint\n" - "\n" " :arg point: A CurvePoint object.\n" " :type point: :class:`CurvePoint`\n" - "\n" - ".. method:: __init__(svertex)\n" - "\n" - " Build a stroke vertex from a SVertex\n" - "\n" " :arg svertex: An SVertex object.\n" " :type svertex: :class:`SVertex`\n" - "\n" - ".. method:: __init__(svertex, attribute)\n" - "\n" - " Build a stroke vertex from an SVertex and a StrokeAttribute object.\n" - "\n" " :arg svertex: An SVertex object.\n" " :type svertex: :class:`SVertex`\n" " :arg attribute: A StrokeAttribute object.\n" diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp index 9295e4f424b..ff53f5bfcbe 100644 --- a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp +++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp @@ -31,22 +31,20 @@ extern "C" { /*----------------------NonTVertex methods ----------------------------*/ -PyDoc_STRVAR(NonTVertex_doc, - "Class hierarchy: :class:`Interface0D` > :class:`ViewVertex` > :class:`NonTVertex`\n" - "\n" - "View vertex for corners, cusps, etc. associated to a single SVertex.\n" - "Can be associated to 2 or more view edges.\n" - "\n" - ".. method:: __init__()\n" - "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(svertex)\n" - "\n" - " Build a NonTVertex from a SVertex.\n" - "\n" - " :arg svertex: An SVertex object.\n" - " :type svertex: :class:`SVertex`"); +PyDoc_STRVAR( + NonTVertex_doc, + "Class hierarchy: :class:`Interface0D` > :class:`ViewVertex` > :class:`NonTVertex`\n" + "\n" + "View vertex for corners, cusps, etc. associated to a single SVertex.\n" + "Can be associated to 2 or more view edges.\n" + "\n" + ".. method:: __init__()\n" + " __init__(svertex)\n" + "\n" + " Builds a :class:`NonTVertex` using the default constructor or a :class:`SVertex`.\n" + "\n" + " :arg svertex: An SVertex object.\n" + " :type svertex: :class:`SVertex`"); /* Note: No copy constructor in Python because the C++ copy constructor is 'protected'. */ diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp index 187ab94360a..e04a89bad3b 100644 --- a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp @@ -48,20 +48,13 @@ PyDoc_STRVAR(FEdge_doc, "from one to the other.\n" "\n" ".. method:: FEdge()\n" + " FEdge(brother)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: FEdge(brother)\n" - "\n" - " Copy constructor.\n" + " Builds an :class:`FEdge` using the default constructor,\n" + " copy constructor, or between two :class:`SVertex` objects.\n" "\n" " :arg brother: An FEdge object.\n" " :type brother: :class:`FEdge`\n" - "\n" - ".. method:: FEdge(first_vertex, second_vertex)\n" - "\n" - " Builds an FEdge going from the first vertex to the second.\n" - "\n" " :arg first_vertex: The first SVertex.\n" " :type first_vertex: :class:`SVertex`\n" " :arg second_vertex: The second SVertex.\n" diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp index 788dfa78992..78c0ee051d6 100644 --- a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp @@ -41,20 +41,14 @@ PyDoc_STRVAR(FrsCurve_doc, "specialization of a Curve.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(id)\n" "\n" - " Default Constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy Constructor.\n" + " Builds a :class:`FrsCurve` using a default constructor,\n" + " copy constructor or from an :class:`Id`.\n" "\n" " :arg brother: A Curve object.\n" " :type brother: :class:`Curve`\n" - "\n" - ".. method:: __init__(id)\n" - "\n" - " Builds a Curve from its Id.\n" - "\n" " :arg id: An Id object.\n" " :type id: :class:`Id`"); diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp index b31efe1f923..910f9cdfa07 100644 --- a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp @@ -50,12 +50,9 @@ PyDoc_STRVAR(Stroke_doc, "defines the stroke's shape and appearance at this vertex position.\n" "\n" ".. method:: Stroke()\n" + " Stroke(brother)\n" "\n" - " Default constructor\n" - "\n" - ".. method:: Stroke(brother)\n" - "\n" - " Copy constructor"); + " Creates a :class:`Stroke` using the default constructor or copy constructor\n"); static int Stroke_init(BPy_Stroke *self, PyObject *args, PyObject *kwds) { @@ -127,21 +124,18 @@ static PyObject *Stroke_compute_sampling(BPy_Stroke *self, PyObject *args, PyObj PyDoc_STRVAR(Stroke_resample_doc, ".. method:: resample(n)\n" + " resample(sampling)\n" "\n" - " Resamples the stroke so that it eventually has N points. That means\n" - " it is going to add N-vertices_size, where vertices_size is the\n" - " number of points we already have. If vertices_size >= N, no\n" - " resampling is done.\n" + " Resamples the stroke so using one of two methods with the goal\n" + " of creating a stroke with fewer points and the same shape.\n" "\n" - " :arg n: The number of vertices we eventually want in our stroke.\n" + " :arg n: Resamples the stroke so that it eventually has N points. That means\n" + " it is going to add N-vertices_size, where vertices_size is the\n" + " number of points we already have. If vertices_size >= N, no\n" + " resampling is done.\n" " :type n: int\n" - "\n" - ".. method:: resample(sampling)\n" - "\n" - " Resamples the stroke with a given sampling. If the sampling is\n" - " smaller than the actual sampling value, no resampling is done.\n" - "\n" - " :arg sampling: The new sampling value.\n" + " :arg sampling: Resamples the stroke with a given sampling value. If the\n" + " sampling is smaller than the actual sampling value, no resampling is done.\n" " :type sampling: float"); static PyObject *Stroke_resample(BPy_Stroke *self, PyObject *args, PyObject *kwds) diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp index 58c2ba69c79..e9160d7a5c7 100644 --- a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp @@ -36,23 +36,21 @@ extern "C" { /*----------------------ViewEdge methods ----------------------------*/ -PyDoc_STRVAR(ViewEdge_doc, - "Class hierarchy: :class:`Interface1D` > :class:`ViewEdge`\n" - "\n" - "Class defining a ViewEdge. A ViewEdge in an edge of the image graph.\n" - "it connects two :class:`ViewVertex` objects. It is made by connecting\n" - "a set of FEdges.\n" - "\n" - ".. method:: __init__()\n" - "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" - "\n" - " :arg brother: A ViewEdge object.\n" - " :type brother: :class:`ViewEdge`"); +PyDoc_STRVAR( + ViewEdge_doc, + "Class hierarchy: :class:`Interface1D` > :class:`ViewEdge`\n" + "\n" + "Class defining a ViewEdge. A ViewEdge in an edge of the image graph.\n" + "it connects two :class:`ViewVertex` objects. It is made by connecting\n" + "a set of FEdges.\n" + "\n" + ".. method:: __init__()\n" + " __init__(brother)\n" + "\n" + " Builds a :class:`ViewEdge` using the default constructor or the copy constructor.\n" + "\n" + " :arg brother: A ViewEdge object.\n" + " :type brother: :class:`ViewEdge`"); static int ViewEdge_init(BPy_ViewEdge *self, PyObject *args, PyObject *kwds) { diff --git a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp index 9cdc344081e..028e36145b9 100644 --- a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp @@ -40,20 +40,14 @@ PyDoc_STRVAR(Chain_doc, "Splitting and Creation processes.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(id)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" + " Builds a :class:`Chain` using the default constructor,\n" + " copy constructor or from an :class:`Id`.\n" "\n" " :arg brother: A Chain object.\n" " :type brother: :class:`Chain`\n" - "\n" - ".. method:: __init__(id)\n" - "\n" - " Builds a chain from its Id.\n" - "\n" " :arg id: An Id object.\n" " :type id: :class:`Id`"); diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp index c329a3badd5..018e0449552 100644 --- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp @@ -42,20 +42,14 @@ PyDoc_STRVAR(FEdgeSharp_doc, "a is None.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(first_vertex, second_vertex)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" + " Builds an :class:`FEdgeSharp` using the default constructor,\n" + " copy constructor, or between two :class:`SVertex` objects.\n" "\n" " :arg brother: An FEdgeSharp object.\n" " :type brother: :class:`FEdgeSharp`\n" - "\n" - ".. method:: __init__(first_vertex, second_vertex)\n" - "\n" - " Builds an FEdgeSharp going from the first vertex to the second.\n" - "\n" " :arg first_vertex: The first SVertex object.\n" " :type first_vertex: :class:`SVertex`\n" " :arg second_vertex: The second SVertex object.\n" diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp index 3fb739b18db..014f0411356 100644 --- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp @@ -39,20 +39,14 @@ PyDoc_STRVAR(FEdgeSmooth_doc, "a suggestive contour.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(first_vertex, second_vertex)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" + " Builds an :class:`FEdgeSmooth` using the default constructor,\n" + " copy constructor, or between two :class:`SVertex`.\n" "\n" " :arg brother: An FEdgeSmooth object.\n" " :type brother: :class:`FEdgeSmooth`\n" - "\n" - ".. method:: __init__(first_vertex, second_vertex)\n" - "\n" - " Builds an FEdgeSmooth going from the first to the second.\n" - "\n" " :arg first_vertex: The first SVertex object.\n" " :type first_vertex: :class:`SVertex`\n" " :arg second_vertex: The second SVertex object.\n" diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp index 90e751333b9..dc32b73fda1 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp @@ -41,20 +41,14 @@ PyDoc_STRVAR( "traverse() method of the ChainingIterator.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(vertex, restrict_to_selection=True, restrict_to_unvisited=True)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" + " Builds an :class:`AdjacencyIterator` using the default constructor,\n" + " copy constructor or the overloaded constructor.\n" "\n" " :arg brother: An AdjacencyIterator object.\n" " :type brother: :class:`AdjacencyIterator`\n" - "\n" - ".. method:: __init__(vertex, restrict_to_selection=True, restrict_to_unvisited=True)\n" - "\n" - " Builds a AdjacencyIterator object.\n" - "\n" " :arg vertex: The vertex which is the next crossing.\n" " :type vertex: :class:`ViewVertex`\n" " :arg restrict_to_selection: Indicates whether to force the chaining\n" diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp index 1703fc2bddb..9c534a3463c 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp @@ -33,55 +33,52 @@ extern "C" { //------------------------INSTANCE METHODS ---------------------------------- -PyDoc_STRVAR(ChainPredicateIterator_doc, - - "Class hierarchy: :class:`freestyle.types.Iterator` >\n" - ":class:`freestyle.types.ViewEdgeIterator` >\n" - ":class:`freestyle.types.ChainingIterator` >\n" - ":class:`ChainPredicateIterator`\n" - "\n" - "A \"generic\" user-controlled ViewEdge iterator. This iterator is in\n" - "particular built from a unary predicate and a binary predicate.\n" - "First, the unary predicate is evaluated for all potential next\n" - "ViewEdges in order to only keep the ones respecting a certain\n" - "constraint. Then, the binary predicate is evaluated on the current\n" - "ViewEdge together with each ViewEdge of the previous selection. The\n" - "first ViewEdge respecting both the unary predicate and the binary\n" - "predicate is kept as the next one. If none of the potential next\n" - "ViewEdge respects these two predicates, None is returned.\n" - "\n" - ".. method:: __init__(upred, bpred, restrict_to_selection=True, " - "restrict_to_unvisited=True, begin=None, " - "orientation=True)\n" - "\n" - " Builds a ChainPredicateIterator from a unary predicate, a binary\n" - " predicate, a starting ViewEdge and its orientation.\n" - "\n" - " :arg upred: The unary predicate that the next ViewEdge must satisfy.\n" - " :type upred: :class:`freestyle.types.UnaryPredicate1D`\n" - " :arg bpred: The binary predicate that the next ViewEdge must\n" - " satisfy together with the actual pointed ViewEdge.\n" - " :type bpred: :class:`freestyle.types.BinaryPredicate1D`\n" - " :arg restrict_to_selection: Indicates whether to force the chaining\n" - " to stay within the set of selected ViewEdges or not.\n" - " :type restrict_to_selection: bool\n" - " :arg restrict_to_unvisited: Indicates whether a ViewEdge that has\n" - " already been chained must be ignored ot not.\n" - " :type restrict_to_unvisited: bool\n" - " :arg begin: The ViewEdge from where to start the iteration.\n" - " :type begin: :class:`freestyle.types.ViewEdge` or None\n" - " :arg orientation: If true, we'll look for the next ViewEdge among\n" - " the ViewEdges that surround the ending ViewVertex of begin. If\n" - " false, we'll search over the ViewEdges surrounding the ending\n" - " ViewVertex of begin.\n" - " :type orientation: bool\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" - "\n" - " :arg brother: A ChainPredicateIterator object.\n" - " :type brother: :class:`ChainPredicateIterator`"); +PyDoc_STRVAR( + ChainPredicateIterator_doc, + + "Class hierarchy: :class:`freestyle.types.Iterator` >\n" + ":class:`freestyle.types.ViewEdgeIterator` >\n" + ":class:`freestyle.types.ChainingIterator` >\n" + ":class:`ChainPredicateIterator`\n" + "\n" + "A \"generic\" user-controlled ViewEdge iterator. This iterator is in\n" + "particular built from a unary predicate and a binary predicate.\n" + "First, the unary predicate is evaluated for all potential next\n" + "ViewEdges in order to only keep the ones respecting a certain\n" + "constraint. Then, the binary predicate is evaluated on the current\n" + "ViewEdge together with each ViewEdge of the previous selection. The\n" + "first ViewEdge respecting both the unary predicate and the binary\n" + "predicate is kept as the next one. If none of the potential next\n" + "ViewEdge respects these two predicates, None is returned.\n" + "\n" + ".. method:: __init__(upred, bpred, restrict_to_selection=True, " + " restrict_to_unvisited=True, begin=None, " + " orientation=True)\n" + " __init__(brother)\n" + "\n" + " Builds a ChainPredicateIterator from a unary predicate, a binary\n" + " predicate, a starting ViewEdge and its orientation or using the copy constructor.\n" + "\n" + " :arg upred: The unary predicate that the next ViewEdge must satisfy.\n" + " :type upred: :class:`freestyle.types.UnaryPredicate1D`\n" + " :arg bpred: The binary predicate that the next ViewEdge must\n" + " satisfy together with the actual pointed ViewEdge.\n" + " :type bpred: :class:`freestyle.types.BinaryPredicate1D`\n" + " :arg restrict_to_selection: Indicates whether to force the chaining\n" + " to stay within the set of selected ViewEdges or not.\n" + " :type restrict_to_selection: bool\n" + " :arg restrict_to_unvisited: Indicates whether a ViewEdge that has\n" + " already been chained must be ignored ot not.\n" + " :type restrict_to_unvisited: bool\n" + " :arg begin: The ViewEdge from where to start the iteration.\n" + " :type begin: :class:`freestyle.types.ViewEdge` or None\n" + " :arg orientation: If true, we'll look for the next ViewEdge among\n" + " the ViewEdges that surround the ending ViewVertex of begin. If\n" + " false, we'll search over the ViewEdges surrounding the ending\n" + " ViewVertex of begin.\n" + " :type orientation: bool\n" + " :arg brother: A ChainPredicateIterator object.\n" + " :type brother: :class:`ChainPredicateIterator`"); static int check_begin(PyObject *obj, void *v) { diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp index d8ad82d667c..9fa84d5f6b8 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp @@ -48,9 +48,10 @@ PyDoc_STRVAR(ChainSilhouetteIterator_doc, "precedence of the silhouette over the crease criterion.\n" "\n" ".. method:: __init__(restrict_to_selection=True, begin=None, orientation=True)\n" + " __init__(brother)\n" "\n" " Builds a ChainSilhouetteIterator from the first ViewEdge used for\n" - " iteration and its orientation.\n" + " iteration and its orientation or the copy constructor.\n" "\n" " :arg restrict_to_selection: Indicates whether to force the chaining\n" " to stay within the set of selected ViewEdges or not.\n" @@ -62,11 +63,6 @@ PyDoc_STRVAR(ChainSilhouetteIterator_doc, " false, we'll search over the ViewEdges surrounding the ending\n" " ViewVertex of begin.\n" " :type orientation: bool\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" - "\n" " :arg brother: A ChainSilhouetteIterator object.\n" " :type brother: :class:`ChainSilhouetteIterator`"); diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp index dbd6e8dd09d..d24e1dc527d 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp @@ -46,11 +46,12 @@ PyDoc_STRVAR( "they will be included in the adjacency iterator (i.e, the adjacent\n" "iterator will only stop on \"valid\" edges).\n" "\n" - ".. method:: __init__(restrict_to_selection=True, restrict_to_unvisited=True, begin=None, " - "orientation=True)\n" + ".. method:: __init__(restrict_to_selection=True, restrict_to_unvisited=True," + " begin=None, orientation=True)\n" + " __init__(brother)\n" "\n" " Builds a Chaining Iterator from the first ViewEdge used for\n" - " iteration and its orientation.\n" + " iteration and its orientation or by using the copy constructor.\n" "\n" " :arg restrict_to_selection: Indicates whether to force the chaining\n" " to stay within the set of selected ViewEdges or not.\n" @@ -63,11 +64,6 @@ PyDoc_STRVAR( " :arg orientation: The direction to follow to explore the graph. If\n" " true, the direction indicated by the first ViewEdge is used.\n" " :type orientation: bool\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" - "\n" " :arg brother: \n" " :type brother: ChainingIterator"); diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp index 6c496b0308b..8eac657316e 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp @@ -39,20 +39,14 @@ PyDoc_STRVAR(CurvePointIterator_doc, "through the .object attribute.\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(step=0.0)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" + " Builds a CurvePointIterator object using either the default constructor,\n" + " copy constructor, or the overloaded constructor.\n" "\n" " :arg brother: A CurvePointIterator object.\n" " :type brother: :class:`CurvePointIterator`\n" - "\n" - ".. method:: __init__(step=0.0)\n" - "\n" - " Builds a CurvePointIterator object.\n" - "\n" " :arg step: A resampling resolution with which the curve is resampled.\n" " If zero, no resampling is done (i.e., the iterator iterates over\n" " initial vertices).\n" diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp index 734ed0117f4..f7afc7695ae 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp @@ -38,17 +38,13 @@ PyDoc_STRVAR(Interface0DIterator_doc, "this iterator is always obtained from a 1D element.\n" "\n" ".. method:: __init__(brother)\n" + " __init__(it)\n" "\n" - " Copy constructor.\n" + " Construct a nested Interface0DIterator using either the copy constructor\n" + " or the constructor that takes an he argument of a Function0D.\n" "\n" " :arg brother: An Interface0DIterator object.\n" " :type brother: :class:`Interface0DIterator`\n" - "\n" - ".. method:: __init__(it)\n" - "\n" - " Construct a nested Interface0DIterator that can be the argument of\n" - " a Function0D.\n" - "\n" " :arg it: An iterator object to be nested.\n" " :type it: :class:`SVertexIterator`, :class:`CurvePointIterator`, or\n" " :class:`StrokeVertexIterator`"); diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp index 4a5927ff6eb..83c504081c1 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp @@ -32,39 +32,33 @@ extern "C" { //------------------------INSTANCE METHODS ---------------------------------- -PyDoc_STRVAR(SVertexIterator_doc, - "Class hierarchy: :class:`Iterator` > :class:`SVertexIterator`\n" - "\n" - "Class representing an iterator over :class:`SVertex` of a\n" - ":class:`ViewEdge`. An instance of an SVertexIterator can be obtained\n" - "from a ViewEdge by calling verticesBegin() or verticesEnd().\n" - "\n" - ".. method:: __init__()\n" - "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" - "\n" - " :arg brother: An SVertexIterator object.\n" - " :type brother: :class:`SVertexIterator`\n" - "\n" - ".. method:: __init__(vertex, begin, previous_edge, next_edge, t)\n" - "\n" - " Build an SVertexIterator that starts iteration from an SVertex\n" - " object v.\n" - "\n" - " :arg vertex: The SVertex from which the iterator starts iteration.\n" - " :type vertex: :class:`SVertex`\n" - " :arg begin: The first SVertex of a ViewEdge.\n" - " :type begin: :class:`SVertex`\n" - " :arg previous_edge: The previous FEdge coming to vertex.\n" - " :type previous_edge: :class:`FEdge`\n" - " :arg next_edge: The next FEdge going out from vertex.\n" - " :type next_edge: :class:`FEdge`\n" - " :arg t: The curvilinear abscissa at vertex.\n" - " :type t: float"); +PyDoc_STRVAR( + SVertexIterator_doc, + "Class hierarchy: :class:`Iterator` > :class:`SVertexIterator`\n" + "\n" + "Class representing an iterator over :class:`SVertex` of a\n" + ":class:`ViewEdge`. An instance of an SVertexIterator can be obtained\n" + "from a ViewEdge by calling verticesBegin() or verticesEnd().\n" + "\n" + ".. method:: __init__()\n" + " __init__(brother)\n" + " __init__(vertex, begin, previous_edge, next_edge, t)" + "\n" + " Build an SVertexIterator using either the default constructor, copy constructor,\n" + " or the overloaded constructor that starts iteration from an SVertex object vertex.\n" + "\n" + " :arg brother: An SVertexIterator object.\n" + " :type brother: :class:`SVertexIterator`\n" + " :arg vertex: The SVertex from which the iterator starts iteration.\n" + " :type vertex: :class:`SVertex`\n" + " :arg begin: The first SVertex of a ViewEdge.\n" + " :type begin: :class:`SVertex`\n" + " :arg previous_edge: The previous FEdge coming to vertex.\n" + " :type previous_edge: :class:`FEdge`\n" + " :arg next_edge: The next FEdge going out from vertex.\n" + " :type next_edge: :class:`FEdge`\n" + " :arg t: The curvilinear abscissa at vertex.\n" + " :type t: float"); static int SVertexIterator_init(BPy_SVertexIterator *self, PyObject *args, PyObject *kwds) { diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp index cda4031240b..e1b24e768e3 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp @@ -48,12 +48,10 @@ PyDoc_STRVAR(StrokeVertexIterator_doc, "by calling Interface0DIterator(it).\n" "\n" ".. method:: __init__()\n" + " __init__(brother)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" + " Creates a :class:`StrokeVertexIterator` using either the\n" + " default constructor or the copy constructor.\n" "\n" " :arg brother: A StrokeVertexIterator object.\n" " :type brother: :class:`StrokeVertexIterator`"); diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp index 3d0ed5d5a4d..20134057864 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp @@ -40,9 +40,10 @@ PyDoc_STRVAR(ViewEdgeIterator_doc, "on a given ViewEdge.\n" "\n" ".. method:: __init__(begin=None, orientation=True)\n" + " __init__(brother)\n" "\n" " Builds a ViewEdgeIterator from a starting ViewEdge and its\n" - " orientation.\n" + " orientation or the copy constructor.\n" "\n" " :arg begin: The ViewEdge from where to start the iteration.\n" " :type begin: :class:`ViewEdge` or None\n" @@ -51,11 +52,6 @@ PyDoc_STRVAR(ViewEdgeIterator_doc, " false, we'll search over the ViewEdges surrounding the ending\n" " ViewVertex of begin.\n" " :type orientation: bool\n" - "\n" - ".. method:: __init__(brother)\n" - "\n" - " Copy constructor.\n" - "\n" " :arg brother: A ViewEdgeIterator object.\n" " :type brother: :class:`ViewEdgeIterator`"); diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp index fe6210468d1..30b7b3ccde5 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp @@ -39,12 +39,10 @@ PyDoc_STRVAR(orientedViewEdgeIterator_doc, "obtained from a ViewVertex by calling edges_begin() or edges_end().\n" "\n" ".. method:: __init__()\n" + " __init__(iBrother)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(iBrother)\n" - "\n" - " Copy constructor.\n" + " Creates an :class:`orientedViewEdgeIterator` using either the\n" + " default constructor or the copy constructor.\n" "\n" " :arg iBrother: An orientedViewEdgeIterator object.\n" " :type iBrother: :class:`orientedViewEdgeIterator`"); diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp index 88705c41204..b59e27dcea9 100644 --- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp @@ -160,13 +160,10 @@ static char UnaryFunction1DDouble___doc__[] = ":class:`Interface1D` and return a float value.\n" "\n" ".. method:: __init__()\n" + " __init__(integration_type)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(integration_type)\n" - "\n" - " Builds a unary 1D function using the integration method given as\n" - " argument.\n" + " Builds a unary 1D function using the default constructor\n" + " or the integration method given as an argument.\n" "\n" " :arg integration_type: An integration method.\n" " :type integration_type: :class:`IntegrationType`\n"; diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp index 3cfc5464296..2f5a59f9c7a 100644 --- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp @@ -65,13 +65,10 @@ static char UnaryFunction1DEdgeNature___doc__[] = ":class:`Interface1D` and return a :class:`Nature` object.\n" "\n" ".. method:: __init__()\n" + " __init__(integration_type)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(integration_type)\n" - "\n" - " Builds a unary 1D function using the integration method given as\n" - " argument.\n" + " Builds a unary 1D function using the default constructor\n" + " or the integration method given as an argument.\n" "\n" " :arg integration_type: An integration method.\n" " :type integration_type: :class:`IntegrationType`\n"; diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp index 4fdc68a2e89..e11d21b6c8e 100644 --- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp @@ -56,13 +56,10 @@ static char UnaryFunction1DFloat___doc__[] = ":class:`Interface1D` and return a float value.\n" "\n" ".. method:: __init__()\n" + " __init__(integration_type)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(integration_type)\n" - "\n" - " Builds a unary 1D function using the integration method given as\n" - " argument.\n" + " Builds a unary 1D function using the default constructor\n" + " or the integration method given as an argument.\n" "\n" " :arg integration_type: An integration method.\n" " :type integration_type: :class:`IntegrationType`\n"; diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp index 218afa3ff10..e04a5b9d7f4 100644 --- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp @@ -65,13 +65,10 @@ static char UnaryFunction1DUnsigned___doc__[] = ":class:`Interface1D` and return an int value.\n" "\n" ".. method:: __init__()\n" + " __init__(integration_type)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(integration_type)\n" - "\n" - " Builds a unary 1D function using the integration method given as\n" - " argument.\n" + " Builds a unary 1D function using the default constructor\n" + " or the integration method given as an argument.\n" "\n" " :arg integration_type: An integration method.\n" " :type integration_type: :class:`IntegrationType`\n"; diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp index 939ccfb8905..f8d75640811 100644 --- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp @@ -71,13 +71,10 @@ static char UnaryFunction1DVec2f___doc__[] = ":class:`Interface1D` and return a 2D vector.\n" "\n" ".. method:: __init__()\n" + " __init__(integration_type)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(integration_type)\n" - "\n" - " Builds a unary 1D function using the integration method given as\n" - " argument.\n" + " Builds a unary 1D function using the default constructor\n" + " or the integration method given as an argument.\n" "\n" " :arg integration_type: An integration method.\n" " :type integration_type: :class:`IntegrationType`\n"; diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp index 02b6373cce4..9f71fb3840b 100644 --- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp @@ -64,13 +64,10 @@ static char UnaryFunction1DVec3f___doc__[] = ":class:`Interface1D` and return a 3D vector.\n" "\n" ".. method:: __init__()\n" + " __init__(integration_type)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(integration_type)\n" - "\n" - " Builds a unary 1D function using the integration method given as\n" - " argument.\n" + " Builds a unary 1D function using the default constructor\n" + " or the integration method given as an argument.\n" "\n" " :arg integration_type: An integration method.\n" " :type integration_type: :class:`IntegrationType`\n"; diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp index b2020e9f554..cb4982f4532 100644 --- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp @@ -80,13 +80,10 @@ static char UnaryFunction1DVectorViewShape___doc__[] = "objects.\n" "\n" ".. method:: __init__()\n" + " __init__(integration_type)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(integration_type)\n" - "\n" - " Builds a unary 1D function using the integration method given as\n" - " argument.\n" + " Builds a unary 1D function using the default constructor\n" + " or the integration method given as an argument.\n" "\n" " :arg integration_type: An integration method.\n" " :type integration_type: :class:`IntegrationType`\n"; diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp index 7b25daa24f9..46564cdaeca 100644 --- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp @@ -79,13 +79,10 @@ static char UnaryFunction1DVoid___doc__[] = ":class:`Interface1D`.\n" "\n" ".. method:: __init__()\n" + " __init__(integration_type)\n" "\n" - " Default constructor.\n" - "\n" - ".. method:: __init__(integration_type)\n" - "\n" - " Builds a unary 1D function using the integration method given as\n" - " argument.\n" + " Builds a unary 1D function using either a default constructor\n" + " or the integration method given as an argument.\n" "\n" " :arg integration_type: An integration method.\n" " :type integration_type: :class:`IntegrationType`\n"; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c index 6eb12974408..8f17be97710 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c @@ -101,6 +101,11 @@ static void deformStroke(GpencilModifierData *md, } BKE_gpencil_stroke_subdivide(gps, mmd->level, mmd->type); + + /* If the stroke is cyclic, must generate the closing geometry. */ + if (gps->flag & GP_STROKE_CYCLIC) { + BKE_gpencil_stroke_close(gps); + } } static void bakeModifier(struct Main *UNUSED(bmain), diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl index 3708b8b0531..3bd578e1ffc 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl @@ -450,7 +450,7 @@ void node_bsdf_principled_glass(vec4 base_color, eevee_closure_glass(N, vec3(1.0), - vec3(1.0), + vec3((use_multiscatter != 0.0) ? 1.0 : -1.0), int(ssr_id), roughness, 1.0, diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c index 2826bd63cc1..607ab95f0b4 100644 --- a/source/blender/imbuf/intern/util_gpu.c +++ b/source/blender/imbuf/intern/util_gpu.c @@ -97,6 +97,7 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, { const bool is_float_rect = (ibuf->rect_float != NULL); void *data_rect = (is_float_rect) ? (void *)ibuf->rect_float : (void *)ibuf->rect; + bool freedata = false; if (is_float_rect) { /* Float image is already in scene linear colorspace or non-color data by @@ -104,7 +105,7 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, * currently. */ if (ibuf->channels != 4 || !store_premultiplied) { data_rect = MEM_mallocN(sizeof(float[4]) * ibuf->x * ibuf->y, __func__); - *r_freedata = true; + *r_freedata = freedata = true; if (data_rect == NULL) { return NULL; @@ -124,7 +125,7 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, * and consistency with float images. */ if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { data_rect = MEM_mallocN(sizeof(uchar[4]) * ibuf->x * ibuf->y, __func__); - *r_freedata = true; + *r_freedata = freedata = true; if (data_rect == NULL) { return NULL; @@ -147,6 +148,10 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, ImBuf *scale_ibuf = IMB_allocFromBuffer(rect, rect_float, ibuf->x, ibuf->y, 4); IMB_scaleImBuf(scale_ibuf, UNPACK2(rescale_size)); + if (freedata) { + MEM_freeN(data_rect); + } + data_rect = (is_float_rect) ? (void *)scale_ibuf->rect_float : (void *)scale_ibuf->rect; *r_freedata = true; /* Steal the rescaled buffer to avoid double free. */ diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 37b7947dbea..713f5ee2afa 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -775,6 +775,7 @@ typedef enum eBrushFlags2 { BRUSH_POSE_USE_LOCK_ROTATION = (1 << 5), BRUSH_CLOTH_USE_COLLISION = (1 << 6), BRUSH_AREA_RADIUS_PRESSURE = (1 << 7), + BRUSH_GRAB_SILHOUETTE = (1 << 8), } eBrushFlags2; typedef enum { diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 92ee3f062a6..c95e5376670 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -690,8 +690,10 @@ typedef enum eBConstraint_Types { /* flag 0x20 (1 << 5) was used to indicate that a constraint was evaluated * using a 'local' hack for posebones only. */ typedef enum eBConstraint_Flags { +#ifdef DNA_DEPRECATED_ALLOW /* Expansion for old box constraint layouts. Just for versioning. */ CONSTRAINT_EXPAND_DEPRECATED = (1 << 0), +#endif /* pre-check for illegal object name or bone name */ CONSTRAINT_DISABLE = (1 << 2), /* to indicate which Ipo should be shown, maybe for 3d access later too */ diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index 7e2ec8b6c65..3a9f9bd7b66 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -57,7 +57,9 @@ typedef enum GpencilModifierMode { eGpencilModifierMode_Realtime = (1 << 0), eGpencilModifierMode_Render = (1 << 1), eGpencilModifierMode_Editmode = (1 << 2), +#ifdef DNA_DEPRECATED_ALLOW eGpencilModifierMode_Expanded_DEPRECATED = (1 << 3), +#endif eGpencilModifierMode_Virtual = (1 << 4), } GpencilModifierMode; diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index e2837ba85f8..a822a6723fa 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -48,7 +48,6 @@ struct MPropCol; struct MVert; struct Material; struct Mesh; -struct Multires; struct SubdivCCG; # @@ -230,9 +229,6 @@ typedef struct Mesh { * default and Face Sets can be used without affecting the color of the mesh. */ int face_sets_color_default; - /** Deprecated multiresolution modeling data, only keep for loading old files. */ - struct Multires *mr DNA_DEPRECATED; - Mesh_Runtime runtime; } Mesh; diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 45bf6e8c282..7cc94a2ad0b 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -518,54 +518,4 @@ typedef struct MRecast { int i; } MRecast; -/** Multires structs kept for compatibility with old files. */ -typedef struct MultiresCol { - float a, r, g, b; -} MultiresCol; - -typedef struct MultiresColFace { - /* vertex colors */ - MultiresCol col[4]; -} MultiresColFace; - -typedef struct MultiresFace { - unsigned int v[4]; - unsigned int mid; - char flag, mat_nr, _pad[2]; -} MultiresFace; - -typedef struct MultiresEdge { - unsigned int v[2]; - unsigned int mid; -} MultiresEdge; - -typedef struct MultiresLevel { - struct MultiresLevel *next, *prev; - - MultiresFace *faces; - MultiresColFace *colfaces; - MultiresEdge *edges; - - unsigned int totvert, totface, totedge; - char _pad[4]; - - /* Kept for compatibility with even older files */ - MVert *verts; -} MultiresLevel; - -typedef struct Multires { - ListBase levels; - MVert *verts; - - unsigned char level_count, current, newlvl, edgelvl, pinlvl, renderlvl; - unsigned char use_col, flag; - - /* Special level 1 data that cannot be modified from other levels */ - CustomData vdata; - CustomData fdata; - short *edge_flags; - char *edge_creases; -} Multires; -/* End multi-res structs. */ - /** \} */ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 3df80e1157d..414c21fd428 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -106,8 +106,10 @@ typedef enum ModifierMode { eModifierMode_Render = (1 << 1), eModifierMode_Editmode = (1 << 2), eModifierMode_OnCage = (1 << 3), - /* Old modifier box expansion, just for versioning. */ +#ifdef DNA_DEPRECATED_ALLOW + /** Old modifier box expansion, just for versioning. */ eModifierMode_Expanded_DEPRECATED = (1 << 4), +#endif eModifierMode_Virtual = (1 << 5), eModifierMode_ApplyOnSpline = (1 << 6), eModifierMode_DisableTemporary = (1u << 31), diff --git a/source/blender/makesdna/DNA_shader_fx_types.h b/source/blender/makesdna/DNA_shader_fx_types.h index 5bb78edb280..5567d65b6db 100644 --- a/source/blender/makesdna/DNA_shader_fx_types.h +++ b/source/blender/makesdna/DNA_shader_fx_types.h @@ -49,7 +49,9 @@ typedef enum ShaderFxMode { eShaderFxMode_Realtime = (1 << 0), eShaderFxMode_Render = (1 << 1), eShaderFxMode_Editmode = (1 << 2), +#ifdef DNA_DEPRECATED_ALLOW eShaderFxMode_Expanded_DEPRECATED = (1 << 3), +#endif } ShaderFxMode; typedef enum { diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index ad032a6d7b6..4a02ac8f429 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -633,10 +633,9 @@ typedef struct UserDef_Experimental { char use_new_hair_type; char use_new_point_cloud_type; char use_sculpt_vertex_colors; - char use_tools_missing_icons; char use_switch_object_operator; char use_sculpt_tools_tilt; - char _pad[6]; + char _pad[7]; /** `makesdna` does not allow empty structs. */ } UserDef_Experimental; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 3f7e3e61d56..4b4e17b38bd 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -383,6 +383,19 @@ enum { KMI_EXPANDED = (1 << 1), KMI_USER_MODIFIED = (1 << 2), KMI_UPDATE = (1 << 3), + /** + * When set, ignore events with #wmEvent.is_repeat enabled. + * + * \note this flag isn't cleared when editing/loading the key-map items, + * so it may be set in cases which don't make sense (modifier-keys or mouse-motion for example). + * + * Knowing if an event may repeat is something set at the operating-systems event handling level + * so rely on #wmEvent.is_repeat being false non keyboard events instead of checking if this + * flag makes sense. + * + * Only used when: `ISKEYBOARD(kmi->type) || (kmi->type == KM_TEXTINPUT)` + * as mouse, 3d-mouse, timer... etc never repeat. + */ KMI_REPEAT_IGNORE = (1 << 4), }; diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index d119be66916..6f227ec210c 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -2968,6 +2968,12 @@ static void rna_def_brush(BlenderRNA *brna) "Apply the maximum grab strength to the active vertex instead of the cursor location"); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "use_grab_silhouette", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_GRAB_SILHOUETTE); + RNA_def_property_ui_text( + prop, "Grab Silhouette", "Grabs trying to automask the silhouette of the object"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "use_paint_antialiasing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "sampling_flag", BRUSH_PAINT_ANTIALIASING); RNA_def_property_ui_text(prop, "Anti-Aliasing", "Smooths the edges of the strokes"); diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 653056e4dc1..76b419926a1 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -512,6 +512,17 @@ static void rna_Constraint_influence_update(Main *bmain, Scene *scene, PointerRN rna_Constraint_update(bmain, scene, ptr); } +/* Update only needed so this isn't overwritten on first evaluation. */ +static void rna_Constraint_childof_inverse_matrix_update(Main *bmain, + Scene *scene, + PointerRNA *ptr) +{ + bConstraint *con = ptr->data; + bChildOfConstraint *data = con->data; + data->flag &= ~CHILDOF_SET_INVERSE; + rna_Constraint_update(bmain, scene, ptr); +} + static void rna_Constraint_ik_type_set(struct PointerRNA *ptr, int value) { bConstraint *con = ptr->data; @@ -999,7 +1010,8 @@ static void rna_def_constraint_childof(BlenderRNA *brna) RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Inverse Matrix", "Transformation matrix to apply before"); - RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); + RNA_def_property_update( + prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_childof_inverse_matrix_update"); RNA_define_lib_overridable(false); } diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 061026288e6..c31766efe58 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -6175,10 +6175,6 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Switch Object Operator", "Enable the operator to switch objects by pressing D"); - prop = RNA_def_property(srna, "use_tools_missing_icons", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "use_tools_missing_icons", 1); - RNA_def_property_ui_text(prop, "Tools with Missing Icons", "Show tools with missing icons"); - prop = RNA_def_property(srna, "use_sculpt_tools_tilt", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "use_sculpt_tools_tilt", 1); RNA_def_property_ui_text( diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index 47d5e9b6313..2c373eb8d46 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -632,6 +632,7 @@ static wmEvent *rna_Window_event_add_simulate(wmWindow *win, wmEvent e = *win->eventstate; e.type = type; e.val = value; + e.is_repeat = false; e.x = x; e.y = y; /* Note: KM_MOD_FIRST, KM_MOD_SECOND aren't used anywhere, set as bools */ @@ -1134,7 +1135,7 @@ void RNA_api_keymapitems(StructRNA *srna) RNA_def_boolean(func, "alt", 0, "Alt", ""); RNA_def_boolean(func, "oskey", 0, "OS Key", ""); RNA_def_enum(func, "key_modifier", rna_enum_event_type_items, 0, "Key Modifier", ""); - RNA_def_boolean(func, "repeat", true, "Repeat", "When set, accept key-repeat events"); + RNA_def_boolean(func, "repeat", false, "Repeat", "When set, accept key-repeat events"); RNA_def_boolean(func, "head", 0, @@ -1158,7 +1159,7 @@ void RNA_api_keymapitems(StructRNA *srna) RNA_def_boolean(func, "alt", 0, "Alt", ""); RNA_def_boolean(func, "oskey", 0, "OS Key", ""); RNA_def_enum(func, "key_modifier", rna_enum_event_type_items, 0, "Key Modifier", ""); - RNA_def_boolean(func, "repeat", true, "Repeat", "When set, accept key-repeat events"); + RNA_def_boolean(func, "repeat", false, "Repeat", "When set, accept key-repeat events"); parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item"); RNA_def_function_return(func, parm); diff --git a/source/blender/makesrna/intern/rna_wm_gizmo.c b/source/blender/makesrna/intern/rna_wm_gizmo.c index 971991869e2..27d46e4d25b 100644 --- a/source/blender/makesrna/intern/rna_wm_gizmo.c +++ b/source/blender/makesrna/intern/rna_wm_gizmo.c @@ -61,6 +61,8 @@ # include "MEM_guardedalloc.h" +# include "GPU_state.h" + # ifdef WITH_PYTHON # include "BPY_extern.h" # endif @@ -84,6 +86,8 @@ static void rna_gizmo_draw_cb(const struct bContext *C, struct wmGizmo *gz) RNA_parameter_set_lookup(&list, "context", &C); gzgroup->type->rna_ext.call((bContext *)C, &gz_ptr, func, &list); RNA_parameter_list_free(&list); + /* This callback may have called bgl functions. */ + GPU_bgl_end(); } static void rna_gizmo_draw_select_cb(const struct bContext *C, struct wmGizmo *gz, int select_id) @@ -101,6 +105,8 @@ static void rna_gizmo_draw_select_cb(const struct bContext *C, struct wmGizmo *g RNA_parameter_set_lookup(&list, "select_id", &select_id); gzgroup->type->rna_ext.call((bContext *)C, &gz_ptr, func, &list); RNA_parameter_list_free(&list); + /* This callback may have called bgl functions. */ + GPU_bgl_end(); } static int rna_gizmo_test_select_cb(struct bContext *C, struct wmGizmo *gz, const int location[2]) diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c index 94dc8a8c43b..17d716b731c 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.c +++ b/source/blender/modifiers/intern/MOD_datatransfer.c @@ -268,7 +268,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL); - uiItemO(layout, "Generate Data Layers", ICON_NONE, "OBJECT_OT_datalayout_transfer"); + uiItemO(layout, IFACE_("Generate Data Layers"), ICON_NONE, "OBJECT_OT_datalayout_transfer"); modifier_panel_end(layout, ptr); } diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index def72af45e8..e0c362171f2 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -492,11 +492,11 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) if (RNA_enum_get(&ob_ptr, "mode") == OB_MODE_EDIT) { row = uiLayoutRow(layout, true); - uiItemO(row, "Reset", ICON_NONE, "OBJECT_OT_hook_reset"); - uiItemO(row, "Recenter", ICON_NONE, "OBJECT_OT_hook_recenter"); + uiItemO(row, IFACE_("Reset"), ICON_NONE, "OBJECT_OT_hook_reset"); + uiItemO(row, IFACE_("Recenter"), ICON_NONE, "OBJECT_OT_hook_recenter"); row = uiLayoutRow(layout, true); - uiItemO(row, "Select", ICON_NONE, "OBJECT_OT_hook_select"); - uiItemO(row, "Assign", ICON_NONE, "OBJECT_OT_hook_assign"); + uiItemO(row, IFACE_("Select"), ICON_NONE, "OBJECT_OT_hook_select"); + uiItemO(row, IFACE_("Assign"), ICON_NONE, "OBJECT_OT_hook_assign"); } modifier_panel_end(layout, ptr); diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index c4f0fff72dd..8886d3718c9 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -230,8 +230,9 @@ static void vertex_group_panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); col = uiLayoutColumn(layout, false); - uiItemPointerR(col, ptr, "shell_vertex_group", &ob_ptr, "vertex_groups", "Shell", ICON_NONE); - uiItemPointerR(col, ptr, "rim_vertex_group", &ob_ptr, "vertex_groups", "Rim", ICON_NONE); + uiItemPointerR( + col, ptr, "shell_vertex_group", &ob_ptr, "vertex_groups", IFACE_("Shell"), ICON_NONE); + uiItemPointerR(col, ptr, "rim_vertex_group", &ob_ptr, "vertex_groups", IFACE_("Rim"), ICON_NONE); } static void panelRegister(ARegionType *region_type) diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index 554ab2645a7..a580b4f10f0 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -82,6 +82,7 @@ static PyTypeObject BlenderAppType; static PyStructSequence_Field app_info_fields[] = { {"version", "The Blender version as a tuple of 3 numbers. eg. (2, 83, 1)"}, + {"version_file", "The blend file version, compatible with ``bpy.data.version``"}, {"version_string", "The Blender version formatted as a string"}, {"version_cycle", "The release status of this build alpha/beta/rc/release"}, {"version_char", "Deprecated, always an empty string"}, @@ -151,6 +152,8 @@ static PyObject *make_app_info(void) SetObjItem( PyC_Tuple_Pack_I32(BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_VERSION_PATCH)); + SetObjItem(PyC_Tuple_Pack_I32( + BLENDER_FILE_VERSION / 100, BLENDER_FILE_VERSION % 100, BLENDER_FILE_SUBVERSION)); SetStrItem(BKE_blender_version_string()); SetStrItem(STRINGIFY(BLENDER_VERSION_CYCLE)); diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c index eece782f6d0..49a3f114ebb 100644 --- a/source/blender/python/mathutils/mathutils_noise.c +++ b/source/blender/python/mathutils/mathutils_noise.c @@ -140,11 +140,11 @@ static void next_state(void) left = N; next = state; - for (j = N - M + 1; j--; p++) { + for (j = N - M + 1; --j; p++) { *p = p[M] ^ TWIST(p[0], p[1]); } - for (j = M; j--; p++) { + for (j = M; --j; p++) { *p = p[M - N] ^ TWIST(p[0], p[1]); } diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index b23446e0dce..a8d24205268 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -503,6 +503,9 @@ typedef struct wmGesture { /** For gestures that support snapping, stores if snapping is enabled using the modal keymap * toggle. */ uint use_snap : 1; + /** For gestures that support flip, stores if flip is enabled using the modal keymap + * toggle. */ + uint use_flip : 1; /** * customdata @@ -556,7 +559,12 @@ typedef struct wmEvent { /** From ghost, fallback if utf8 isn't set. */ char ascii; - /** Generated by auto-repeat. */ + /** + * Generated by auto-repeat, note that this must only ever be set for keyboard events + * where `ISKEYBOARD(event->type) == true`. + * + * See #KMI_REPEAT_IGNORE for details on how key-map handling uses this. + */ char is_repeat; /** Previous state, used for double click and the 'click'. */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index e6ec68f706c..8eb9a3b0650 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -155,6 +155,15 @@ wmEvent *WM_event_add_simulate(wmWindow *win, const wmEvent *event_to_add) void wm_event_free(wmEvent *event) { +#ifndef NDEBUG + /* Don't use assert here because it's fairly harmless in most cases, + * more an issue of correctness, something we should avoid in general. */ + if (event->is_repeat && !ISKEYBOARD(event->type)) { + printf("%s: 'is_repeat=true' for non-keyboard event, this should not happen.\n", __func__); + WM_event_print(event); + } +#endif + if (event->customdata) { if (event->customdatafree) { /* Note: pointer to listbase struct elsewhere. */ @@ -3402,6 +3411,7 @@ void wm_event_do_handlers(bContext *C) tevent.type = MOUSEMOVE; tevent.prevx = tevent.x; tevent.prevy = tevent.y; + tevent.is_repeat = false; wm_event_add(win, &tevent); win->addmousemove = 0; } diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index ae8b78876c2..4c1b403ac96 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -200,7 +200,7 @@ int wm_gesture_evaluate(wmGesture *gesture, const wmEvent *event) /* ******************* gesture draw ******************* */ -static void wm_gesture_draw_line_active_side(rcti *rect) +static void wm_gesture_draw_line_active_side(rcti *rect, const bool flip) { GPUVertFormat *format = immVertexFormat(); uint shdr_pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -222,7 +222,9 @@ static void wm_gesture_draw_line_active_side(rcti *rect) sub_v2_v2v2(line_dir, line_end, line_start); normalize_v2(line_dir); ortho_v2_v2(gradient_dir, line_dir); - mul_v2_fl(gradient_dir, -1.0f); + if (!flip) { + mul_v2_fl(gradient_dir, -1.0f); + } mul_v2_fl(gradient_dir, gradient_length); add_v2_v2v2(gradient_point[0], line_start, gradient_dir); add_v2_v2v2(gradient_point[1], line_end, gradient_dir); @@ -252,7 +254,7 @@ static void wm_gesture_draw_line(wmGesture *gt) rcti *rect = (rcti *)gt->customdata; if (gt->draw_active_side) { - wm_gesture_draw_line_active_side(rect); + wm_gesture_draw_line_active_side(rect, gt->use_flip); } uint shdr_pos = GPU_vertformat_attr_add( diff --git a/source/blender/windowmanager/intern/wm_gesture_ops.c b/source/blender/windowmanager/intern/wm_gesture_ops.c index 00112e82771..edf9a3bc693 100644 --- a/source/blender/windowmanager/intern/wm_gesture_ops.c +++ b/source/blender/windowmanager/intern/wm_gesture_ops.c @@ -851,6 +851,7 @@ static bool gesture_straightline_apply(bContext *C, wmOperator *op) RNA_int_set(op->ptr, "ystart", rect->ymin); RNA_int_set(op->ptr, "xend", rect->xmax); RNA_int_set(op->ptr, "yend", rect->ymax); + RNA_boolean_set(op->ptr, "flip", gesture->use_flip); if (op->type->exec) { int retval = op->type->exec(C, op); @@ -892,6 +893,7 @@ int WM_gesture_straightline_active_side_invoke(bContext *C, wmOperator *op, cons WM_gesture_straightline_invoke(C, op, event); wmGesture *gesture = op->customdata; gesture->draw_active_side = true; + gesture->use_flip = false; return OPERATOR_RUNNING_MODAL; } @@ -950,6 +952,11 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev gesture->use_snap = !gesture->use_snap; break; } + case GESTURE_MODAL_FLIP: { + /* Toggle snapping on/off. */ + gesture->use_flip = !gesture->use_flip; + break; + } case GESTURE_MODAL_SELECT: { if (gesture_straightline_apply(C, op)) { gesture_modal_end(C, op); @@ -1029,6 +1036,11 @@ int WM_gesture_straightline_oneshot_modal(bContext *C, wmOperator *op, const wmE gesture->use_snap = !gesture->use_snap; break; } + case GESTURE_MODAL_FLIP: { + /* Toggle flip on/off. */ + gesture->use_flip = !gesture->use_flip; + break; + } case GESTURE_MODAL_SELECT: case GESTURE_MODAL_DESELECT: case GESTURE_MODAL_IN: diff --git a/source/blender/windowmanager/intern/wm_operator_props.c b/source/blender/windowmanager/intern/wm_operator_props.c index 78d8fc9a20d..62294d70306 100644 --- a/source/blender/windowmanager/intern/wm_operator_props.c +++ b/source/blender/windowmanager/intern/wm_operator_props.c @@ -498,6 +498,8 @@ void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor) RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); prop = RNA_def_int(ot->srna, "yend", 0, INT_MIN, INT_MAX, "Y End", "", INT_MIN, INT_MAX); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "flip", false, "Flip", ""); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); if (cursor) { prop = RNA_def_int(ot->srna, diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5e4a45ea3be..613de5a9b17 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3807,6 +3807,7 @@ static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf) {GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""}, {GESTURE_MODAL_MOVE, "MOVE", 0, "Move", ""}, {GESTURE_MODAL_SNAP, "SNAP", 0, "Snap", ""}, + {GESTURE_MODAL_FLIP, "FLIP", 0, "Flip", ""}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 21662a4e83a..223f6cf543d 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -496,6 +496,9 @@ enum { /** Toggle to activate snapping (angle snapping for straight line). */ GESTURE_MODAL_SNAP = 13, + + /** Toggle to activate flip (flip the active side of a straight line). */ + GESTURE_MODAL_FLIP = 14, }; #ifdef __cplusplus diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 47ab96bbc7e..3b54811657d 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -48,6 +48,7 @@ # include "BKE_blender_version.h" # include "BKE_context.h" +# include "BKE_appdir.h" # include "BKE_global.h" # include "BKE_image.h" # include "BKE_lib_id.h" @@ -56,9 +57,7 @@ # include "BKE_scene.h" # include "BKE_sound.h" -# ifdef WITH_FFMPEG -# include "IMB_imbuf.h" -# endif +# include "IMB_imbuf.h" # ifdef WITH_PYTHON # include "BPY_extern_python.h" @@ -1205,6 +1204,8 @@ static int arg_handle_playback_mode(int argc, const char **argv, void *UNUSED(da { /* not if -b was given first */ if (G.background == 0) { + BKE_appdir_init(); + IMB_init(); # ifdef WITH_FFMPEG /* Setup FFmpeg with current debug flags. */ IMB_ffmpeg_init(); |